Search code examples
nunjuckseleventy

How can I specify an 11ty collection in frontmatter?


On my website, I want to show a list of collection items on pages corresponding to each collection. For example on the Games page, I want to show a list of all game related articles, on the Politics page, I want to show a list of all politics related articles, etc.

What I have right now is one Nunjucks template file for each such page, which I don't particularly like since they are the same except for the collection to show. Here is two of my templates, for my politics articles and for my games articles, where I extend a common boilerplate (base.njk) and in the main block, I first print some Markdown content and then comes the list of collection items:

{# politics.njk #}

{% extends "base.njk" %}

{% block main %}
<main>
    {{ content | safe }}
    <ul class="postlist no-bullets">
        {% for item in collections.politics %}
            {% include "partials/collection-list-item.njk" %}
        {% endfor %}
    </ul>
</main>
{% endblock %}
{# games.njk #}

{% extends "base.njk" %}

{% block main %}
<main>
    {{ content | safe }}
    <ul class="postlist no-bullets">
        {% for item in collections.games %}
            {% include "partials/collection-list-item.njk" %}
        {% endfor %}
    </ul>
</main>
{% endblock %}

As you can see, the only difference between these two files is collections.politics and collections.games. I would want to use one template, and in the frontmatter specify which collection I want. Since I'm already having one Markdown file per page the template used (for writing stuff before I begin listing articles), it would have been nice if it was possible. For example:

<!-- politics.md -->
---
layout: articles-list.njk
title: Politics
listCollection: collections.politics
---
# Politics
Below is a list of all politics articles I've written.
<!-- games.md -->
---
layout: articles-list.njk
title: Games
listCollection: collections.games
---
# Games
I think about games a lot. Below is a list of articles I've written on the topic.
{# articles-list.njk #}

{% extends "base.njk" %}

{% block main %}
<main>
    {{ content | safe }}
    <ul class="postlist no-bullets">
        {% for item in listCollection %}
            {% include "partials/collection-list-item.njk" %}
        {% endfor %}
    </ul>
</main>
{% endblock %}

Is it possible to do what I want to do in some other way than to have multiple template files?


Solution

  • You might be able to get to the collection using computed data, though I'm not sure if you have access to the collections there.

    A simpler approach: Set your frontmatter field to the name of the colletion you want to display as a string, then use that to get the collection in the template:

    <!-- politics.md -->
    ---
    layout: articles-list.njk
    title: Politics
    listCollection: 'politics'
    ---
    
    {# articles-list.njk #}
    
    {% extends "base.njk" %}
    
    {% block main %}
    <main>
        {{ content | safe }}
        <ul class="postlist no-bullets">
            {% for item in collections[listCollection] %}
                {% include "partials/collection-list-item.njk" %}
            {% endfor %}
        </ul>
    </main>
    {% endblock %}