Calling all eleventy collections automatically in separate figures?

What I’m wanting to do is basically a for loop to list the pages under every collection, but in its own layout.

Eg. the code for one collection for me would look something like this:

<figure>
<h2>Characters</h2>
<ul>
{% for post in collections.characters %}
<li>{{ post.data.title }}</li>
{% endfor %}
</figure>

I want to do this for every collection automatically, so each one is in its own figure with the title of the collection. Is that possible, or would I need another approach?

If your collections are based on tags, you could create a custom collection of all tags in your .eleventy.js config file like so:

/* .eleventy.js */

module.exports = config => {
    config.addCollection('allTags', collection => {
        const allCollections = collection.getAll();
        let tagSet = new Set();
        allCollections.forEach(temp => {
            if('tags' in temp.data) {
                for(const tag of temp.data.tags) {
                    tagSet.add(tag);
                }
            }
        });
        return [...tagSet];
    });
}

Then, you can use that custom collection as so:

{% for allCollections in collections.allTags %}
{% set post = collections[allCollections] %}
<figure>
    <h2>{{ allCollections }}</h2>
    <ul>
        {% for p in post %}
            <li>{{ p.data.title }}</li>
        {% endfor %}
    </ul>
</figure>
{% endfor %}

In this case, the text content of the h2 element would be the tag itself. I hope I answered your question correctly.

2 Likes

Wow, that worked, thank you! That is a major hurdle out of the way that I could not figure out :sweat_smile: Now I need to figure out sorting and then I’m pretty much done with this section of my project :smiley:

1 Like

I’m super glad this worked for you! :hugs:

1 Like

Hi, I just rediscovered quick tip #004 and it inspired me a much simpler solution based on the principle that it’s possible to iterate through the collections object itself.

The collections object is an object keyed with tag names pointing to the collection of content containing that tag.

Loosely quoted from quick tip #004

So to list all tags with its own content, it would look something like this in Nunjucks:

template.njk

{% for tag, tagCollection in collections %}
    {% if tag !== "all" %}
    <figure>
      <h2>{{ tag }}</h2>
      <ul>
        {% for post in tagCollection %}
            <li>{{ post.data.title }}</li>
        {% endfor %}
      </ul>
    </figure>
    {% endif %}
{% endfor %}

Here, I use the if statement to “filter out” the all collection which is in collections by default, but it could be use to remove any collection from the displayed result. The good news with this is that you don’t need a custom collection anymore which greatly reduces the overhead! If you want to see the content of collections for yourself, you can use {{ collections | log }} in any template to display the object in the console (works in version 0.11.0 and up)!