Closed pepelsbey closed 4 years ago
I want this in like... every project I ever build.
Hm, would it be limited to Markdown?
I mean, as a tech blogger I could refer to CSS or JS files and would have them included as well. Or take preprocessors (SASS or CoffeeScript).
It would be great to be able to preprocess any other included formats, not just Markdown. But this might require hacking the way {% include %}
works, I’m not sure if it’s possible.
I +1d this issue because I have the same desire as the OP, and I like the outcome they recommend.
I am a bit bemused because I don't understand why markdown in my templates is not being included, when the 11ty docs state that You can use any template language in your layout.
I've raised it as an issue here but not had any response yet.
I am a bit out of my depth here and rather confused, but hoping someone will help me see the light, as I would like to start being creative with eleventy templates but as yet I don't understand them well enough. And I am finding that the documentation is not helping me get out of my stuck situation.
Hm, would it be limited to Markdown?
I mean, as a tech blogger I could refer to CSS or JS files and would have them included as well. Or take preprocessors (SASS or CoffeeScript).
According to the docs, JS is already supported as a template language (which I think is what @pepelsbey is asking for)?
No, that was not what I head in mind. I'm sorry for not being clear enough.
Look, I use my website as playground. Now, say, that I am trying some JavaScript to try something out. Instead of having to copy its content into a blog post I wondered whether I could have some Nunjucks filter in my Markdown to refer to the file and include its content as within code fences.
Could be stupid down the road (when I iterate over the JS file), but it was an idea.
I'm also fine with focussing on Markdown filter first. Sometimes it helps planning of you keep in mind that it could be more generic. On the other hand YAGNI.
I'm uncertain and thus asked.
@Ryuno-Ki I expect it's me who is not clear! I'm very confused... :-) I guess I am just stuck at the point of working out the difference between what you are suggesting and what eleventy already provides in terms of templating functionality, i.e. I don't really understand why it is that what you want to do doesn't already work, when 11ty already supports md/js as template languages.
My guess: Nobody pushed a PR for adding the file to https://github.com/11ty/eleventy/tree/b5613504a9524dfeb8be8c00a3c30d24313f4325/src/Filters
You basically have what you need in the OP.
I started working on adding this as a universal filter, but then figured it might be more appropriate as an extension, rather than expanding the scope of what universal filters do.
A quick first draft: https://www.npmjs.com/package/eleventy-plugin-markdown-shortcode
Does this help you out @pepelsbey?
Personally I am trying to include a .njk file which contains both nunjucks and markdown, but only the nunjucks is being rendered.
I had hoped your plugin above would work, but alas it only renders markdown.
@mashdot - I'm using it in my own nunjucks without issue. I keep the markdown files in the _includes
directory, include them through the shortcode, and it sptis out my markdown content inside nunjucks.
What's the part missing for you?
If put the {% include "test.md" %}
directly within a markdown page, it will render the markdown and nunjucks.
(I also have markdownTemplateEngine: "njk",
configured in .eleventy.js
)
However as soon as I move the include up a level into a .njk layout the nunjucks is rendered but not the markdown. However all existing markdown and nunjucks in the page is rendered correctly. (So the layout templating already works fine)
e.g. # {{ title }}
gets rendered as # title of the page
rather than <h1>title of the page</h1>
If instead I use {% markdown "/_includes/test.md" %}
what gets rendered is <h1>{{ title }}</h1>
Maybe I have my config confused, but basically I want to work with html,md,njk files and that I suppose in order njk, md, html should be rendered. I assumed I could simply include a file with any of that content and it would all "eventually" get rendered on output.
Ah I see, plugin I wrote works for a more limited use case where you have a .njk file and you want to include a .md file (composed entirely and only of markdown) and have it rendered as HTML for the .njk file to process.
BTW I discovered how to get it to work! Although not directly related to the topic, adding comments here which may be helpful to others in the future.
In my .eleventy.js
I have markdownTemplateEngine: "njk"
and htmlTemplateEngine: "njk"
set.
I then changed my layout to .md
extension. These are composed of html, nunjucks, and markdown.
My include file is now .md
and contains html, nunjucks, and markdown, and simply using the standard {% include "partials/footer.md" %}
in the parent layout gets included and rendered.
So basically keep the layouts and includes as .md
files and set markdownTemplateEngine: "njk"
.
Another idea (untested):
Using set to capture a block - the {% include %}
part - and then process the markdown within.
@Ryuno-Ki, that’s exactly what I’m doing right now, mentioned in the first comment.
Here is how I'm tackling this. Not too different from @pepelsbey 's solution and perhaps not as robust as @ogdenstudios 's package. Simple to use though.
In .njk file:
{% set snippet %}{% include './content/my-markdown.md' %}{% endset %}
{% markdown snippet %}
In eleventy.config.js
:
// Note: You do not need to add markdown-it to package.json.
let markdown = require("markdown-it")({
html: true
});
module.exports = config => {
...
config.addNunjucksShortcode(
"markdown",
content => `<div class="md-block">${markdown.render(content)}</div>`
);
...
};
And if you didn't want to use and intermediate {% set %}
(Nunjucks) or {% capture %}
(Liquid), you could use a paired shortcode:
const markdownIt = require("markdown-it");
module.exports = function (eleventyConfig) {
const md = new markdownIt({
html: true
});
eleventyConfig.addPairedShortcode("markdown", (content) => {
return md.render(content);
});
return {
dir: {
input: "src",
output: "www"
}
};
};
<h1>Markdown in Nunjucks</h1>
{% markdown %}
{%- include "my-markdown.md" -%}
{% endmarkdown %}
Yup! That's about right. It's been working for me for months now with no real issue.
And if you didn't want to use and intermediate
{% set %}
(Nunjucks) or{% capture %}
(Liquid), you could use a paired shortcode:const markdownIt = require("markdown-it"); module.exports = function (eleventyConfig) { const md = new markdownIt({ html: true }); eleventyConfig.addPairedShortcode("markdown", (content) => { return md.render(content); }); return { dir: { input: "src", output: "www" } }; };
<h1>Markdown in Nunjucks</h1> {% markdown %} {%- include "my-markdown.md" -%} {% endmarkdown %}
@pdehaan Thanks so much for the solution. It's exactly what I've been stuck on.
However, when I try it, I get "Error: template not found:" for my my-markdown.md. It's as if my eleventy thinks my-markdown.md should be a my-markdown.njk, despite the it's layout front matter points provides the path to its layout. I've tried relative & absolute paths.
I tried some of the other solutions proposed & yield the same response.
my config includes:
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk",
};
and my dir config is the default.
Any help would be greatly appreciated!
@stevenmilstein I posted a simple example at https://github.com/pdehaan/11ty-658
If you want to include a file relative to the current .njk template, you might need to prefix the path with ./
:
{% markdown %}
{%- include "./my-markdown.md" -%}
{% endmarkdown %}
Although this had the unexpected side effect of compiling the included the partial "./my-markdown.md" file into the destination folder's "./www/my-markdown/index.html", which isn't what I wanted.
Or apparently if you're including from your ./src/_includes/
directory, you can include it directly:
{% markdown %}
{%- include "foo.md" -%}
{% endmarkdown %}
@pdehaan Thanks so much for the timely reply.
I guess my problem is that my markdowns use different layout njk. I'll submit a PR with my modifications. For some reason, the layouts are not working.
Thanks again for your time!
Hey sorry y’all—I believe this is a duplicate of #148.
This is an old issue but I wanted to pass on my solution to importing many MD files to one page with 11ty. All my MD content files use the base layout. So effectively the base.njk will populate the main MD content but also import another MD file I use for my navigation links
source: https://www.11ty.dev/docs/plugins/render/#usage
.eleventy.js
const { EleventyRenderPlugin } = require("@11ty/eleventy");
module.exports = config => {
...
// add 11ty render function to use in njk files
config.addPlugin(EleventyRenderPlugin);
...
_includes\layouts\nav.njk
{% renderFile "./Navigation/navLinks.md" %}
_includes\layouts\base.njk
...
<div class="navMenu" >
{% include './nav.njk' %}
</div>
...
<div class='layout-post main-container'>
<div class='centered'>
<div class='column'>
<div class='ui basic segment'>
{{ content | safe }}
</div>
</div>
</div>
</div>
<footer>
...
Is your feature request related to a problem? Please describe.
I often want to include Markdown snippets of content into my templates. It’s super convenient to store them in Markdown, not HTML. But inclusion won’t render them, it would just include what’s there untouched, and it’s fare.
Describe the solution you'd like
Wouldn’t that be wonderful if Evelenty could expose a default
markdown
filter (along withurl
andslug
) that does the same thing with Markdown using built-in renderer?The most convenient solution would be:
But I’m not sure that would work.
Describe alternatives you've considered
I made a custom filter to render snippets after inclusion:
And then:
But in this case I need to have the same
markdown-it
installed in mypackage.json
and initialized as a filter in my config, though it’s already available and widely used by Eleventy.