На начало 2017 года в Jekyll нет штатного, из коробки, решения для тегов. Они же метки.

Что мы ждём от тегов в блоге?

  • Определённо нужна возможность найти посты по какому-то тегу. Значит должен быть или список всех постов с группировкой по тегам, или, лучше, отдельные страницы по каждому тегу.

  • Хорошо было бы получить список тегов. Ещё лучше если в этом списке будут сразу видны часто используемые теги.

В сети предлагают изобретать велосипед с разными плагинами и прочие костыли. Можно проще!

Данный подход подразумевает ручное создание страниц для отдельных тегов. При этом для каждого тега есть возможность добавить описание. Все остальное делается автоматически используя только директивы Liquid. Никакие плагины не нужны.

Страницы отдельных тегов

В Jekyll можно сделать свои коллекции для страниц, аналогичные встроенным для posts и pages.

Коллекция tags уже используется, потому допишем в _config.yml определение для коллекции topics.

collections:
  topics:
    output: true
    permalink: /topics/:name/

Файлы Jekyll будет искать в каталоге с бревном перед именем коллекции.

mkdir -p _topics/

Имена файлов в этом каталоге должны совпадать с тегами. Если у вас есть тег jekyll, то ему соответствует _topics/jekyll.markdown.

---
layout: topic
title:  "Всё о Jekyll"
---

[Jekyll](https://jekyllrb.com/) - генератор статических сайтов.

Если у вас есть какой-то тег, который вы не хотите показывать со списоком постов, то достаточно будет не создавать одноименный ему файл. Всё в ваших руках.

Шаблон для страницы тега

Список постов по тегу выводим из шаблона topic.

Шаблон _layouts/topic.html оформить можно как удобно. Важно соблюдать общую структуру.

{% if site.tags[page.slug] %}
  {% for post in site.tags[page.slug] %}
    <!-- Ссылка на пост -->
  {% endfor %}
{% endif %}

Пример реализации

За основу для шаблона возьмем page.html.

cp _layouts/page.html _layouts/topic.html

Или, если у вас нет каталога _layouts, найдем встроенные шаблоны.

find $(bundle show $(grep ^theme _config.yml | cut -f2 -d:))/_layouts

Скопируем шаблоны для доработки из темы.

mkdir -p _layouts
theme_dir=$(bundle show $(grep ^theme _config.yml | cut -f2 -d:))
cp $theme_dir/_layouts/* _layouts/
cp _layouts/page.html _layouts/topic.html
cat _layouts/home.html >> _layouts/topic.html

Перед закрывающим тегом в _layouts/topic.html допишем вывод списка постов для текущего тега по аналогии с _layouts/home.html или index.html.

Вместо списка всех постов site.posts используем список постов из site.tags[page.slug] для одноименного со страницей тега.

{% if site.tags[page.slug] %}
<div class="home">
  <ul class="post-list">
    {% for post in site.tags[page.slug] %}
    <li>
      <span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
      <h2>
        <a class="post-link" href="{{ post.url | relative_url }}">
          {{ post.title | escape }}
        </a>
      </h2>
    </li>
    {% endfor %}
 </ul>
</div>
{% endif %}

Теги в посте

Для показа списка тегов со ссылками в _layouts/post.html в любом подходящем месте добавим их перечисление.

{% if page.tags %}
<ul class="post-tags">  
{% for tag in page.tags %}
  {% assign found_tags = site.topics | where: "slug", tag %}
  {% for tag in found_tags limit:1 %} 
  <li><a href="{{ tag.url }}" title="{{ tag.title }}">{{ tag.slug }}</a></li>
  {% endfor %}
{% endfor %}
</ul>
{% endif %}

При перечислении проверяем что для тега есть страница. Если страницы нет, то тег не показываем. Если страница есть, то используем её данные для ссылки.

Список всех тегов

Нужен шаблон для показа списка _includes/topics.html


<div class="home">
  {% for page in site.topics %}
  {% if page.title and site.tags[page.slug] and page.hidden != true %}
    <h2>
    <a class="post-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>
    </h2>
  {% endif %}
  {% endfor %}
</div>

И страница _pages/topics.markdown под список тегов.

---
layout: default
title: Все темы
permalink: /topics/
---
{% include topics.html %}

Все!

Запускайте jekyll serve и ищите список тегов на странице каждого поста. Например, на этом сайте.

Cписок всех тегов

Если вы перечисляете теги в формате YML, то получим список всех тегов с частотой использования.

ls _posts/*-* |
  xargs -n1 ruby -ryaml -e "puts YAML::load(open(ARGV.first).read)['tags']" |
  sort | uniq -c | sort -rh

Создадим все файлы для тегов по шаблону.

ls _posts/*-* |
  xargs -n1 ruby -ryaml -e "puts YAML::load(open(ARGV.first).read)['tags']" |
  sort | uniq -c |
while read weight tag
do
    test -f "_topics/$tag.markdown" && continue
    export tag weight
    envsubst < _topics/template.envsubst > "_topics/$tag.markdown"
done

Шаблон с переменными в привычном для shell виде.

---
layout: topic
title:  "Всё о $tag"
canonical: $tag
weight: $weight
---

[$tag](#) — это

Credits

Эти инструкции были бы невозможны без поста Стефана Гросса. Спасибо ему.

Источник вдохновения для стиля меток.