11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
16.76k stars 484 forks source link

Accessing collections inside macros #434

Open mirisuzanne opened 5 years ago

mirisuzanne commented 5 years ago

I often want to access collections from inside nunjucks macros, which are walled off from the global scope. If I could create a collections shortcode, I could access them anywhere, without needing a special argument to pass collections into macros.

Is it possible to access my collections inside the .eleventy.js config, in order to create that shortcode?

mirisuzanne commented 5 years ago

Sorry, shortcodes are the wrong approach here, since they return template literals and strings, not objects… Maybe need to rethink my approach…

edwardhorsford commented 5 years ago

@mirisuzanne If you want, you can give the global scope to macros when you import them, like this: {% import "includes/macros.njk" as macro with context %}

mirisuzanne commented 5 years ago

Oh, that's useful to know! Though full global context comes with it's own downsides… :)

Am I right that it's not really possible to access collections in the config, to create a filter e.g. collection_name | getPosts that would be available from anywhere?

zachleat commented 5 years ago

Collections are available in the config but only inside of Collection Configuration API: https://www.11ty.io/docs/collections/#advanced%3A-custom-filtering-and-sorting

Hmm, I’m not sure how safe it is to try and combine those two things together in your config file.

Can you provide a more concrete example so I can see the value of what you’re doing? Examples help me understand

AlahmadiQ8 commented 5 years ago

I had a similar issue and @edwardhorsford with context advice solved my problem. I simply wanted to access global data inside a macro. I just learn about with context.

mirisuzanne commented 5 years ago

I have various components that include a list of tags, with linked tag pages – but the tag_list macro needs access to collections in order to get that information – unless I pass it into every component explicitly, which is my current solution.

AlahmadiQ8 commented 5 years ago

@mirisuzanne I see what you mean. I will probably run into that as well at some point.

I'm curious if setting a variable as a workaround.

like

{% set tags post.data.tags %} 
{% import "includes/macros.njk" as macro with context %}

would tags be accessible in the macro without having to pass it in?

I'll give that a try tonight

mirisuzanne commented 5 years ago

with context should do it – just means I have to do a lot of namespace cleanup to avoid conflicts.