Коли сайт на Eleventy розростається, у шаблонах і статтях починають повторюватися однакові шматки: вставка аудіо чи відео, блоки з примітками, форматування дат. Щоб не копіювати їх щоразу, в Eleventy є два зручні інструменти – шорткоди і фільтри. Різниця між ними проста:

  • шорткод вставляє готовий шматок HTML: пишеш у статті один короткий рядок – отримуєш на сторінці повноцінний блок;
  • фільтр перетворює значення: бере, наприклад, дату чи рядок і повертає їх у потрібному вигляді.

Обидва реєструються у файлі налаштувань eleventy.config.js. Якщо в тебе його ще немає, почни зі статті про те, як створити статичний сайт на Eleventy.

Як зареєструвати шорткод в Eleventy

Розгляньмо на прикладі, яким я сам користувався: шорткод для вставки аудіо через HTML5-тег <audio>. Додай у файл налаштувань:

export default function (eleventyConfig) {
  eleventyConfig.addShortcode("audio", function (src) {
    return `<audio controls src="${src}">Твій браузер не підтримує відтворення аудіо.</audio>`;
  });
}

Змінна src – це шлях до аудіофайлу, який ти передаєш у шорткод. Тепер у статті в Markdown досить написати:

{% audio "/audio/song.mp3" %}

І після збирання сайту на сторінці з'явиться готовий плеєр:

<audio controls src="/audio/song.mp3">Твій браузер не підтримує відтворення аудіо.</audio>

Порада, на якій я свого часу спіткнувся: у Markdown-файлах повертай із шорткоду HTML без відступів на початку рядків. Eleventy спершу підставляє шорткод, а потім обробляє Markdown, і рядки з відступом у чотири пробіли перетворюються на блок коду, а переноси – на зайві <br>. Тому найпростіше повертати весь тег одним рядком, як у прикладі вище.

Шорткод із кількома параметрами

Параметрів може бути скільки завгодно. Наприклад, шорткод для відео з YouTube, де передаються ідентифікатор ролика і його назва:

eleventyConfig.addShortcode("youtube", function (id, title = "Відео") {
  return `<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/${id}" title="${title}" loading="lazy" allowfullscreen></iframe>`;
});
{% youtube "M7lc1UVf-VE", "Мій улюблений кліп" %}

Другий параметр має значення за замовчуванням, тож його можна й не вказувати.

Парний шорткод

Буває, що шорткод має обгорнути цілий шматок тексту – скажімо, виділити примітку чи попередження. Для цього є парні шорткоди:

eleventyConfig.addPairedShortcode("note", function (content, type = "info") {
  // порожні рядки дозволяють Markdown обробити текст усередині блоку
  return `<div class="note note-${type}">\n\n${content}\n\n</div>`;
});
{% note "warning" %}
Перед оновленням **обов'язково** зроби резервну копію сайту.
{% endnote %}

Перший аргумент функції – це текст між відкривальним і закривальним тегами, а далі йдуть звичайні параметри. Залишається лише оформити клас .note у CSS.

Як створити фільтр в Eleventy

Фільтри найкраще пояснювати на датах – саме з ними в Eleventy виникає перше непорозуміння. Якщо вивести в шаблоні дату статті як є, {{ page.date }}, отримаєш довжелезний рядок на кшталт:

Fri Oct 16 2020 03:00:00 GMT+0300 (Eastern European Summer Time)

Колись я викручувався, вирізаючи шматки рядка прямо в шаблоні, але з фільтром усе набагато охайніше. Найпростіший варіант не потребує жодних додаткових пакетів – вистачає вбудованих можливостей JavaScript:

export default function (eleventyConfig) {
  // 16 жовтня 2020 р.
  eleventyConfig.addFilter("readableDate", function (date) {
    return new Intl.DateTimeFormat("uk-UA", {
      day: "numeric",
      month: "long",
      year: "numeric",
      timeZone: "Europe/Kyiv"
    }).format(date);
  });

  // 2020-10-16 - для атрибута datetime
  eleventyConfig.addFilter("htmlDate", function (date) {
    return date.toISOString().slice(0, 10);
  });
}

Тепер у будь-якому шаблоні дата виводиться так:

<time datetime="{{ page.date | htmlDate }}">{{ page.date | readableDate }}</time>

Відвідувач побачить «16 жовтня 2020 р.», а пошуковики отримають дату в машинному форматі.

Формат дати через Luxon

Якщо потрібен якийсь особливий формат, зручно скористатися бібліотекою Luxon:

npm install luxon
import { DateTime } from "luxon";

export default function (eleventyConfig) {
  eleventyConfig.addFilter("shortDate", function (date) {
    return DateTime.fromJSDate(date, { zone: "Europe/Kyiv" }).toFormat("dd.LL.yyyy");
  });
}

Запис {{ page.date | shortDate }} дасть звичний нам формат 16.10.2020. У рядку формату dd – день, LL – місяць, yyyy – рік, а повний список позначень є в документації Luxon.

Фільтр із параметром

Фільтр, як і шорткод, може приймати параметри. Ось, наприклад, фільтр, який залишає лише кілька перших елементів списку – знадобиться для блоку «Останні статті»:

eleventyConfig.addFilter("limit", function (items, count) {
  return items.slice(0, count);
});
{% for post in collections.posts | reverse | limit(5) %}
  <a href="{{ post.url }}">{{ post.data.title }}</a>
{% endfor %}

Шорткод чи фільтр: що обрати

  • Треба вставити в статтю готовий блок (плеєр, відео, примітку, кнопку) – роби шорткод.
  • Треба змінити вигляд значення (дата, текст, список) – роби фільтр.

Обидва працюють у шаблонах Nunjucks і Liquid, а також у Markdown-файлах. А якщо функцій набереться багато, їх зручно винести в окремий файл і підключати у eleventy.config.js через import.

Далі можна взятися за автоматичне меню та категорії статей. Усі матеріали про цей генератор – за позначкою Eleventy, а більше про JavaScript – за позначкою JavaScript.

А які шорткоди чи фільтри придумав/ла ти? Ділись у коментарях 🙂