Macros list
See original GitHub issueHi
I’ve faced one little issue with macros imports.
I hope someone will suggest some good workaround, otherwise that post can be considered as proposal.
In my projects I’m using a lot of macros. I’ve kept all macros in single _macros.nj
file and imported it into main layout (which extended by all other layouts) like
{# Calling macros globally #}
{% import "_macros.nj" as macro %}
{# --------- #}
It was quite handy, since it allowed me to access any macros on any layout simply with
{{ macro.myMacro }}
So, it worked quite well until project grew really big and I’ve ended up with tons of macros in single plain file.
In my situation it would be wise to split macros into some kind of partials.
For example, like this:
├── nunjucks
│ ├── macros
│ │ ├── _entry.nj
│ │ ├── _product.nj
│ │ ├── _slider.nj
│ │ └── ...
| ├── _layout.nj
| └── index.nj
└── ...
Looks good so far, I though, but then I realized that in fact there is no fashionable way to import all those macros at once as macro
object.
This means that I have very few options:
1) Import each macros with separate import
{% import "_entry.nj" as macroEntry %}
{% import "_product.nj" as macroProduct %}
{% import "_slider.nj" as macroSlider %}
But, well, it simply doesn’t look right and spawns tons of new objects
2) Import macros at pages where I need them
In fact, it’s working solution, but it forces you to spend time on calling of macros at each page. Besides, in case you delete macro, you need to find it on each page and delete — not fun too, especially considering that we have global macros here
3) Go “CSS\Sass way”
In other word, collect all macros in some indexing file:
├── macros
│ ├── _entry.nj
│ ├── _product.nj
│ ├── _slider.nj
│ └── ...
├── _macros.nj ← here is our guy
├── ...
_macros.nj
will looks like
{% include "macros/_entry.nj" %}
{% include "macros/_product.nj" %}
{% include "macros/_slider.nj" %}
...
Then we can import our main macros file in main layout like
{# Calling macros globally #}
{% import "_macros.nj" as macro %}
{# --------- #}
And then magic should happen. But, unfortunately, it won’t, since importing of file which include macros will output nothing.
4) Use wildcards globbing
Just import all macros like
{# Calling macros globally #}
{% import "macros/*.nj" as macro %}
{# --------- #}
And it should pick up all .nj
files with macros from specified path and import them as macro
object`.
It won’t work too, of course, since it’s impossible to use globbing in imports right now.
Now, the question, is it in general bad idea\practice\way to handle macros in such way, or no? Or maybe I’m missing some obvious better solution?
Thanks in advance
Issue Analytics
- State:
- Created 9 years ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
Once again necromancing, but this solution might help someone.
After all those years, all efforts, we could never embrace Jinja’s idea of import with mandatory
as
. It became even worse, when we switched to component-only way of UI building. So, since everything was a component, it was so inconvenient to import everything into new abstract “macros” holders. We wanted single namespace.Fortunately, with help of custom filter or global, you can merge all macros into single variable.
In our case we used lodash. And, well, yes, it also loads all macros in one go into single variable. This is only because Kotsu is a static website generator, so we can afford it. I wouldn’t recommend such greedy loading in browser environment. Probably.
Anyway, here is a snippet. Adopt it to your needs:
Here are example components, here is how loader declared, and here is how you could use those components/macros.
Necromancing once again. Just was passing by, but this might save time for some folks.
A much easier solution would be to use an import, which allows to import specific macro without storing it into an object:
I’m not sure that those named imports are even mentioned in Nunjucks docs. Compare it with the older way, which forces to create not always useful objects: