Как я могу указать 11ти коллекцию во фронтматтере?

На своем веб-сайте я хочу отображать список элементов коллекции на страницах, соответствующих каждой коллекции. Например, на странице Игры я хочу показать список всех статей, связанных с играми, на странице Политика я хочу показать список всех статей, связанных с политикой, и Т. Д.

Сейчас у меня есть по одному файлу шаблона Nunjucks для каждой такой страницы, что мне не особенно нравится, поскольку они одинаковы, за исключением коллекции, которую нужно показать. Вот два моих шаблона для статей о политике и статей об играх, в которых я расширяю общий шаблон (base.njk), а в основном блоке я сначала распечатываю некоторый контент Markdown, а затем перехожу список предметов коллекции:

{# 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 %}

Как видите, единственная разница между этими двумя файлами - collections.politics и collections.games. Я бы хотел использовать один шаблон, а во фронтматоре указать, какую коллекцию я хочу. Поскольку у меня уже есть один файл Markdown на страницу, в которой используется шаблон (для написания материала, прежде чем я начну перечислять статьи), было бы неплохо, если бы это было возможно. Например:

<!-- 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 %}

Можно ли делать то, что я хочу, другим способом, кроме как иметь несколько файлов шаблонов?


person Johan Nilsson    schedule 05.05.2021    source источник


Ответы (2)


Вы можете получить доступ к коллекции, используя вычисленные данные, хотя я не уверен, есть ли у вас там доступ к коллекциям.

Более простой подход: установите в поле frontmatter имя коллекции, которую вы хотите отобразить в виде строки, а затем используйте это, чтобы получить коллекцию в шаблоне:

<!-- 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 %}
person MoritzLost    schedule 06.05.2021
comment
Спасибо! Я перейду к вашему второму предложению. Я никогда не думал, что коллекции являются ассоциативными массивами, потому что в этом вся суть collections[listCollection], не так ли? - person Johan Nilsson; 07.05.2021
comment
@JohanNilsson Ассоциативные массивы не существуют в JS, есть только массивы (которые всегда численно индексируются) и объекты. Вы можете получить доступ к свойствам объекта как с помощью точечной нотации, так и с помощью скобок, последняя в первую очередь полезна именно для этой цели, для доступа к свойству, имя которого берется из переменной. Поскольку коллекции из одиннадцати являются объектами, вы можете динамически обращаться к одной из них, используя переменную в качестве ключа. Nunjucks имитирует это поведение, поэтому работает как в обычном JS, так и в Нанджаки. - person MoritzLost; 07.05.2021
comment
В примере с Nunjucks они эквивалентны: {{ foo.bar }}, {{ foo["bar"] }}. В документации об этом не упоминается, но, конечно, строка "bar" также может поступать из переменной. Вот ресурс по обозначению скобок в JavaScript . - person MoritzLost; 07.05.2021

То, как я сделал это в своем блоге (https://github.com/cfjedimaster/raymondcamden2020), было вот так:

  1. Создаю коллекцию своих категорий. Я делаю это с помощью .eleventy.js и eleventyConfig.addCollection. Я использую некоторый JavaScript, чтобы получать все свои сообщения, перебирать каждый список категорий и создавать уникальный список. В конце концов, у меня есть коллекция под названием категории.
  eleventyConfig.addCollection("categories", collection => {
    let cats = new Set();
        let posts = collection.getFilteredByGlob("_posts/**/*.md");
        for(let i=0;i<posts.length;i++) {
      for(let x=0;x<posts[i].data.categories.length;x++) {
        cats.add(posts[i].data.categories[x].toLowerCase());
      }
        }

        return Array.from(cats).sort();
    });
  1. Затем я создал одну страницу category.liquid, которая отвечает за создание страниц моих категорий. Это довольно просто:
---
pagination:
    data: collections.categories
    size: 1
    alias: cat
permalink: "categories/{{ cat | myEscape }}/"
layout: category
renderData:
    title: "{{ cat }}"
---

Обратите внимание, что я использую cat для каждого элемента в категории и замечаю, что у меня здесь ничего нет. Весь макет выполняется на странице макета категории.

  1. Вот верхняя часть страницы моей категории:
---
layout: default
---

{% assign posts = collections.posts | getByCategory: cat %}

Итак, учитывая, что у меня есть коллекция постов, где каждому посту назначено N категорий, я написал специальный фильтр, который просто сокращает его до поста, в котором cat является одной из категорий.

Конечным результатом является N страниц категорий, заполненных сообщениями, назначенными этой категории.

person Raymond Camden    schedule 06.05.2021
comment
Спасибо! Я знаю о разбиении на страницы, но я хотел, чтобы на страницах моей коллекции был какой-то настраиваемый основной текст, и на каждой из них был разный текст. Я думаю, что собираюсь с ответом @MoritzLost. Я обязательно проверю исходный код вашего блога однажды, чтобы научиться некоторым инструментам торговли. Я новичок в Eleventy. - person Johan Nilsson; 07.05.2021