I'm coming from a node / nunjucks app where I import my macros once in my parent layout template like so:
{% import "includes/macros.html" as macro with context %}
Now all pages that use this template get access to my macros.
I couldn't get this to work with eleventy - it appears like every page needs to reference the macros file individually. It would be great if they could be referenced just the once.
Some conversation on twitter about this:
https://twitter.com/adambsilver/status/1038330552363966464
Is your node/nunjucks app using Nunjucks extends for layouts? We do still support those.
Hmm, this one actually might be difficult to get working with eleventy layouts. Structurally, we render layout-less output of templates for templateContent strings in collection entries.
https://www.11ty.io/docs/collections/#collection-item-data-structure
No, I'm using the Eleventyone project as a starter. I can give extends a try - that's what my existing site uses.
Is the an advantage / disadvantage to using one or the other?
If you use Nunjucks extends for layouts, you can鈥檛 use front matter in your layout to set inherited data. But you can use directory data files to do this same thing https://www.11ty.io/docs/data-template-dir/
The other thing Eleventy layouts gives you is cross-template layout use. Eleventy layouts can use any template language, independent of the child content. This may or may not be important for your project.
I've tried using extends in my layouts and I think it still doesn't work when importing macros in the parent template.
Sounds like this is going to need a new feature to support this request. Possibly a front matter convention鈥攏ot sure yet? I鈥檓 open to ideas!
I've ended up including the import on every page, including templates. It's not a major thing, but a bit annoying.
Thankfully eleventy errors obviously well when it's not included, so I know pretty quickly when I've messed it up.
Of course my ideal would be that each page only has what's unique about that page - with imports and such coming from higher level templates. But I'm not sure it's worth adding more magic to frontmatter to achieve this.
+1 To this request.
I've tried a few tricks to get this working but was fighting Eleventy layouts. I tried creating a nunjucks filter that exposed the addGlobal method but it didn't work, probably with how eleventy preps the templates for render.
Glad I finally found this thread. Spent over an hour trying to get my macros included via templates layouts. Add the import each page manually will be a pain.
I agree! Being able to import my macros in the parent template would be extremely helpful.
@zachleat, I think a front matter convention could work. I'm not sure how this would look for other template languages, but for nunjucks maybe something like?
layout: parent.njk
eleventyImport:
file: macros.njk
as: macro
context: true
---
for multiple imports:
layout: parent.njk
eleventyImport:
- file: macros.njk
as: macro
context: true
- file: my-components.njk
as: components
---
In the meantime, like @edwardhorsford, I'm just including the import on every page.
Not a huge deal. Just a nice to have. Thanks for starting the convo!
This repository is now using lodash style issue management for enhancements. This means enhancement issues will now be closed instead of leaving them open.
View the enhancement backlog here. Don鈥檛 forget to upvote the top comment with 馃憤!
I also spent hours trying to find things online to help with this.
I tried using Nunjucks extends and experienced the same issue. Child templates don't seem to have access to or knowledge of macros imported by parent templates.
Do I really still have to import all of my macros on every template that I want to use them on? Or has there been a solution implemented for this that I just haven't found in the docs yet?
One of my goals with this app I'm building is to eliminate barriers for people to contribute - and my typical user won't want to be bothered with this sort of thing.
@erikwoods I looked at this again last week and still couldn't find a solution. I'd love it if eleventy could do something. Prepend content maybe?
At the moment, I do two things:
macros.njk file. This then gets imported once in each template (my templates have the line already included).Eg in uk gov (example here), the html for the macro is kept separate from the creation of it.
template.njk:
// whatever markup you want to output
macro.njk:
{% macro govukButton(params) %}
{%- include "./template.njk" -%}
{% endmacro %}
What I've I realised last week (when wanting to import all UK gov macros) is that the above format allows me to have one file like:
extraMacros.njk:
{% macro firstComponent(params) %}
{%- include "./firstComponent/template.njk" -%}
{% endmacro %}
{% macro secondComponent(params) %}
{%- include "./secondComponent/template.njk" -%}
{% endmacro %}
This file then gets concatted with my main macros so that they all become available under the macro namespace.
Not ideal, but means you wouldn't have to import _each_ on every single page.
Thanks for the suggestion @edwardhorsford !
I will have to check it out ASAP.
Most helpful comment
I've ended up including the import on every page, including templates. It's not a major thing, but a bit annoying.
Thankfully eleventy errors obviously well when it's not included, so I know pretty quickly when I've messed it up.
Of course my ideal would be that each page only has what's unique about that page - with imports and such coming from higher level templates. But I'm not sure it's worth adding more magic to frontmatter to achieve this.