Меню – перше, що потрібно будь-якому сайту, і в Eleventy його зовсім не обов'язково прописувати вручну. Є офіційний плагін eleventy-navigation: ти позначаєш потрібні сторінки, а він сам збирає з них меню, зокрема багаторівневе, підсвічує активний пункт і навіть будує «хлібні крихти».

Якщо ти ще тільки знайомишся з цим генератором, почни зі статті про те, як створити статичний сайт на Eleventy, а тут розберемо меню від встановлення плагіна до кількох окремих меню на одному сайті.

Встановлення плагіна eleventy-navigation

У кореневій теці проєкту виконай:

npm install @11ty/eleventy-navigation --save-dev

І підключи плагін у файлі налаштувань eleventy.config.js:

import eleventyNavigationPlugin from "@11ty/eleventy-navigation";

export default function (eleventyConfig) {
  eleventyConfig.addPlugin(eleventyNavigationPlugin);
}

Як додати сторінку до меню

Сторінки можуть бути в будь-якому форматі – Markdown, Nunjucks, Liquid чи HTML. Щоб сторінка потрапила в меню, допиши в її front matter (блок між рисками на початку файлу):

---
eleventyNavigation:
  key: Блоґ
---

key – це водночас унікальний ідентифікатор пункту і його назва в меню. Якщо назва має відрізнятися від ключа (скажімо, ключ короткий, а в меню хочеться довший текст), додай title:

---
eleventyNavigation:
  key: Блоґ
  title: Мої нотатки
  order: 2
---

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

Багаторівневе меню

Щоб зробити пункт дочірнім, вкажи ключ батьківського пункту в parent:

---
eleventyNavigation:
  key: JavaScript
  parent: Програмування
  order: 1
---

Рівнів вкладеності може бути скільки завгодно.

Посилання на інший сайт

У меню можна додати і зовнішнє посилання, якому не відповідає жодна сторінка. Для цього створи окремий файл, наприклад menu-github.md, з таким вмістом:

---
permalink: false
eleventyNavigation:
  key: GitHub
  url: https://github.com/
  order: 9
---

permalink: false каже Eleventy не створювати для цього файлу окремої сторінки – він потрібен лише для меню.

Виведення меню в шаблоні

Найпростіше вивести все меню одним рядком у шаблоні Nunjucks (наприклад, у _includes/base.njk):

{{ collections.all | eleventyNavigation | eleventyNavigationToHtml | safe }}

Плагін згенерує звичайний вкладений список <ul> з посиланнями. Щоб його було зручно оформити в CSS і щоб поточна сторінка підсвічувалася, передай кілька параметрів:

{{ collections.all | eleventyNavigation | eleventyNavigationToHtml({
  listClass: "menu",
  activeKey: eleventyNavigation.key,
  activeListItemClass: "active",
  useAriaCurrentAttr: true
}) | safe }}

Тепер пункт поточної сторінки отримає клас active, а посилання на неї – атрибут aria-current="page" (за це відповідає останній параметр), який підказує програмам для незрячих, де саме перебуває відвідувач.

Власна розмітка меню

Якщо готовий список не підходить під дизайн, меню можна вивести циклом і повністю контролювати HTML:

{% set menu = collections.all | eleventyNavigation %}
<nav>
  {%- for item in menu %}
    <a href="{{ item.url }}"{% if item.url == page.url %} class="active"{% endif %}>{{ item.title }}</a>
  {%- endfor %}
</nav>

Дочірні пункти кожного елемента лежать у item.children – їх виводять так само, вкладеним циклом.

Кілька меню на одному сайті

Часто на сайті потрібно два меню: верхнє з пунктами «Головна», «Блоґ», «Контакти» і бокове з категоріями, як на цьому блозі. Записи вище виводять усі позначені сторінки разом, тож розділити їх можна трьома способами.

1. Гілка меню за ключем

Найохайніший варіант – передати у фільтр ключ батьківського пункту. Тоді виведуться лише його дочірні пункти:

{{ collections.all | eleventyNavigation("Програмування") | eleventyNavigationToHtml | safe }}

Тобто категорії достатньо зробити дочірніми пунктами одного батьківського, і бокове меню готове.

2. Окремий тег для кожного меню

Сторінкам одного меню можна дати спільний тег. Зверни увагу: tags пишеться на верхньому рівні front matter, а не всередині eleventyNavigation – на цьому легко помилитися:

---
tags: topmenu
eleventyNavigation:
  key: Контакти
  order: 3
---

А в шаблоні замість усіх сторінок береш лише колекцію з цим тегом:

{{ collections.topmenu | eleventyNavigation | eleventyNavigationToHtml | safe }}

3. Колекція з окремої теки

Якщо сторінок для меню багато, тег у кожній прописувати незручно. Простіше скласти їх в окрему теку і створити з неї колекцію у файлі налаштувань:

eleventyConfig.addCollection("categories", function (collectionApi) {
  return collectionApi.getFilteredByGlob("category/*.njk");
});
{{ collections.categories | eleventyNavigation | eleventyNavigationToHtml | safe }}

Eleventy сприйме це так, ніби кожна сторінка з теки category має тег categories. Як зробити самі категорії з окремими сторінками і списками статей, я розповідав у статті про вкладені категорії в Eleventy.

«Хлібні крихти»

Той самий плагін уміє будувати ланцюжок на кшталт «Програмування › JavaScript», який допомагає і відвідувачам, і пошуковикам зрозуміти структуру сайту:

{% set crumbs = collections.all | eleventyNavigationBreadcrumb(eleventyNavigation.key) %}
<nav class="breadcrumbs">
  {%- for crumb in crumbs %}
    <a href="{{ crumb.url }}">{{ crumb.title }}</a> ›
  {%- endfor %}
  {{ eleventyNavigation.title or eleventyNavigation.key }}
</nav>

Ось і все, що потрібно для зручної навігації. Далі можна спростити собі роботу шорткодами і фільтрами, а всі матеріали про цей генератор знайдеш за позначкою Eleventy.

Скільки меню на твоєму сайті і як ти їх робиш? Пиши в коментарях 🙂