Гайд по Eleventy

Дата последней правки:

Примечание: в примерах используется синтаксис шаблонизатора Nunjucks.

Начало работы

Eleventy предназначен для создания статических веб-сайтов, которые не требуют бэкенда, базы данных или серверного рендеринга. Сайт представляет собой набор готовых файлов, которые можно напрямую разместить на веб-хостинге. Eleventy также используется для создания сложных сайтов с помощью плагинов и API.

Поэтапная установка и запуск Eleventy:

  1. Скачайте и установите Node.js (требуется Node.js версии 18 или выше) и npm.
  2. Проверьте работоспособность:
  1. Создайте папку для будущего проекта (например, eleventy-project): mkdir eleventy-project.
  2. Перейдите в эту папку: cd eleventy-project. Далее все команды в терминале следует вводить из этой папки.
  3. Создайте и настройте файл package.json: npm init -y.
  4. Установите Eleventy локально в проект: npm install --save-dev @11ty/eleventy. Это добавляет запись devDependencies в файл package.json и устанавливает пакет Eleventy в папку node_modules в проекте. Локальная установка означает, что Eleventy будет работать только для файлов внутри этого каталога. После установки в папке проекта появятся папка node_modules и файл package-lock.json. Файл package-lock.json обеспечивает воспроизводимость сборки: любой компьютер с Node.js и npm сможет установить Eleventy в папку node_modules в той же версии, что и у вас. Команда npm install --save-dev @11ty/eleventy@latest обновит Eleventy до последней версии.
  5. Создайте конфигурационный файл .eleventy.js в корне проекта. В этом файле настраивается Eleventy.
  6. Создайте пустой файл .nojekyll в корне проекта. Это необходимо только при размещении сайта на GitHub Pages, чтобы предотвратить обработку сайта как проекта Jekyll (по умолчанию GitHub Pages использует Jekyll для генерации сайтов).
  7. Запустите локальный сервер разработки: npx @11ty/eleventy --serve. Сервер запустится по адресу: http://localhost:8080/. Локальный сервер останавливается комбинацией клавиш Ctrl+C.

По умолчанию Eleventy использует структуру ваших файлов и папок для создания статического сайта.

eleventy-project/
├── package.json                   # Информация о проекте и зависимости проекта
├── node_modules                   # Папка со служебными зависимостями
├── .gitignore                     # Файл с исключениями для системы контроля версий
├── .eleventy.js                   # Основной файл конфигурации Eleventy
├── index.md                       # Главная страница сайта
├── src/                           # Исходные файлы
│   ├── _drafts/                   # Черновики статей
│   ├── _data/                     # Глобальные данные для всего сайта
│   │   └── brands.json            # Файл с данными
│   ├── includes/                  # Шаблоны, которые используются в других страницах
│   │   ├── base.njk               # Базовый HTML-шаблон (head, body, и т. д.)
│   │   ├── post.njk               # Шаблон для отдельных постов в блоге
│   │   └── footer.njk             # Футер страницы
│   ├── scripts/                   # Подключаемые скрипты
│   ├── assets/                    # Исходные ресурсы сайта
│   │   ├── css/                   # Таблица стилей
│   │   ├── img/                   # Изображения
│   │   └── fonts/                 # Шрифты
│   ├── blog/                      # Папка для постов в блоге
│   │   ├── blog.json              # Файл данных для блога
│   │   ├── post-1.md              # Первый пост
│   │   ├── post-2.md              # Второй пост
│   │   └── post-3.md              # Третий пост
└── site/                          # Скомпилированный сайт (папка вывода)
Структура проекта в Eleventy
Структура проекта
Структура проекта в Eleventy

Файл .eleventy.js используется для настройки различных аспектов сайта, таких как указание входных и выходных директорий, добавление поддержки разных шаблонизаторов, определение фильтров и шорткодов для обработки данных, а также подключение плагинов для расширения функциональности Eleventy.

Файл package.json необходим для управления зависимостями проекта, определения скриптов для запуска (например, для сборки или запуска сервера разработки) и отслеживания версий установленных пакетов. Этот файл позволяет воспроизвести среду разработки на любом компьютере.

Любые пути, перечисленные в файле .gitignore, исключаются из отслеживания системой контроля версий.

Папка node_modules хранит установленные через npm/yarn пакеты и их зависимости. Eleventy автоматически игнорирует эту папку.

✒️ Зависимость в программировании — это внешний компонент или библиотека, которую ваш проект использует для выполнения определённых задач.

Основные команды Eleventy:

Команды переопределяются в файле package.json:

{
  "scripts": {
    "start": "eleventy --serve",
    // Запуск сервера разработки
    "build": "cross-env ELEVENTY_ENV=production eleventy"
    // Сборка проекта для релиза (production)
  }
}

Теперь в терминале команда npm start заменяет команду npx @11ty/eleventy --serve.

Сборка сайта в Eleventy
Сборка сайта в Eleventy

Настройки

Все настройки проекта хранятся в файле .eleventy.js (также допускается имя файла — eleventy.config.js):

module.exports = function (eleventyConfig) {
    // Настройка копирования файлов без обработки
    eleventyConfig.addPassthroughCopy('assets');
    eleventyConfig.addPassthroughCopy('**/*.jpg');

    // Фильтр для форматирования дат на русском языке
    eleventyConfig.addFilter("date", function (dateObj) {
        return dateObj.toLocaleDateString('ru-RU', {
            year: 'numeric',
            month: 'long',
            day: 'numeric'
        });
    });

    return {
        dir: {
            input: "src",          // Папка с исходными файлами
            output: "site",        // Папка для сгенерированного сайта
            includes: "includes",  // Папка с шаблонами
            data: "_data"          // Папка с глобальными данными
        },
        templateFormats: [
            "md",     // Markdown
            "njk",    // Nunjucks
            "html"    // HTML
        ],
        markdownTemplateEngine: 'njk',   // Шаблонизатор для Markdown-файлов
        pathPrefix: '/conspect'          // Префикс для всех URL
    };
};
Файл .eleventy.js

module.exports = function (eleventyConfig) — функция, которая принимает объект eleventyConfig, используемый для настройки Eleventy.

eleventyConfig.addPassthroughCopy('assets') — указывает Eleventy копировать все файлы из директории src/assets в выходную директорию без обработки. Файлы скопируются без преобразования или обработки шаблонов. Это полезно для изображений, видео, CSS, JavaScript и шрифтов, так как Eleventy по умолчанию не обрабатывает эти файлы и без функции addPassthroughCopy (сквозное копирование) будет их игнорировать.

Пути для копирования файлов passthroughCopy относительны к корню проекта, а не входному каталогу. При использовании настройки input: "src" и output: "site" в файле .eleventy.js, команда eleventyConfig.addPassthroughCopy('assets') скопирует содержимое папки src/assets в папку site/assets.

eleventyConfig.addPassthroughCopy('**/*.jpg') — копирует все JPG-файлы в проекте в выходную папку, сохраняя структуру каталогов.

templateFormats: ["md", "njk", "html"] — определяет, какие расширения файлов Eleventy будет обрабатывать как шаблоны.

markdownTemplateEngine: 'njk' — устанавливает Nunjucks как движок для Markdown-файлов. Все файлы Markdown будут сначала обработаны Nunjucks, а затем преобразованы в HTML.

dir: { ... } — определяет структуру каталогов проекта.

pathPrefix: '/conspect' — определяет базовый URL для сайта. Если сайт размещается в подкаталоге /conspect домена example.com, то pathPrefix должен быть установлен в /conspect. В этом случае все ссылки на сайте будут начинаться с /conspect (например, /conspect/eleventy).

Eleventy обрабатывает файлы с расширениями, указанными в templateFormats, находящиеся в папке src, и выводит полученный контент в папку site.

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


Шаблоны (Templates)

✒️ Шаблон — это файл контента, который Eleventy преобразует в страницу или страницы на созданном сайте.

Создавая шаблон, мы избавляемся от необходимости вручную копировать и вставлять код каждый раз при создании новой страницы. Шаблоны позволяют комбинировать контент и данные для создания любого HTML-кода, необходимого для сайта. В Eleventy разрешается смешивать разные языки шаблонов в одном файле, например, Markdown и Nunjucks.

По умолчанию Eleventy ищет шаблоны и макеты в папке _includes, которая расположена внутри входной директории (src). Файлы, расположенные в папке src/_includes, не генерируют отдельные страницы, а используются как части других страниц: шаблоны, макеты, включаемые элементы.

Для начала создадим базовые шаблоны для проекта:

  1. Создайте папку includes (см. конфиг .eleventy.js) в папке src.
  2. Внутри папки includes создайте файл base.njk (шаблон макета), который будет содержать основной HTML-каркас для каждой страницы:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <meta content="{{ description }}" name="description">  <!-- Описание страницы (если задано) -->
    <meta content="frontrabotka.github" name="author">
    <title>{{ title | default('Игрушечные модели автомобилей') }}</title>
    <link href="assets/style/main.css" rel="stylesheet">
</head>
<body>
<main>
    {% block content %}
    {{ content | safe }}  <!-- Содержимое страницы, вставляемое сюда -->
    {% endblock %}
</main>
{% include 'footer.njk' %}  <!-- Подключаем футер -->
</body>
</html>
Файл шаблона base.njk (src/includes/base.njk)

{{ description }} — получает значение из Front Matter файла дочерней страницы (например, из src/index.md). Данные могут также поступать из других источников в каскаде данных. Eleventy автоматически подставляет это описание во время сборки (см. раздел «Метаданные»).

Данные в Front Matter переопределяют значения по умолчанию, заданные в шаблоне. Если в Front Matter эти данные отсутствуют, используются значения, заданные в базовом шаблоне или других источниках каскада данных (см. раздел «Каскад данных»).

<title>{{ title | default('Игрушечные модели автомобилей') }}</title> — задаёт заголовок страницы. Фильтр | default в Eleventy используется для установки значения по умолчанию, когда основное значение отсутствует. Если переменная title не определена, используется значение по умолчанию — Игрушечные модели автомобилей.

{% include 'footer.njk' %} — подключает частичный шаблон (partial) footer.njk. Частичные шаблоны — это небольшие, переиспользуемые фрагменты HTML, такие как «подвал», «шапка» или навигация. Использование include позволяет избежать дублирования кода на каждой странице и упрощает внесение изменений (достаточно изменить файл шаблона, и изменения отразятся везде). По умолчанию Eleventy ищет частичные файлы в папке _includes.

{% block content %}...{% endblock %} — определяет блок контента. Блоки используются для наследования шаблонов: дочерние шаблоны могут переопределять содержимое блоков, определённых в родительском шаблоне.

{{ content | safe }} — во время сборки Eleventy автоматически вставляет сюда содержимое из Markdown-файлов и других источников данных. Фильтр | safe отключает автоматическое экранирование HTML, позволяя выводить HTML-контент без изменений.

Создадим шаблон «подвала» сайта в папке src/includes/footer.njk:

<p>© 2025</p>
Шаблон «подвала» сайта: footer.njk (src/includes/footer.njk)

Наверх


Макеты (Layouts)

✒️ Макет — это шаблон, определяющий общую структуру страницы, в которую «оборачивается» содержимое других шаблонов.

Макеты придают нескольким шаблонам одинаковую базовую структуру.

Согласно настройкам в .eleventy.js, Eleventy ищет макеты в папке src/includes/.

Создадим дополнительные страницы сайта:

  1. Создайте в папке src/ файл index.md. Это будет главная страница сайта:
---
layout: base.njk  <!-- Указываем макет base.njk -->
title: Игрушечные модели автомобилей  <!-- Этот заголовок будет отображён в теге <title> (см. base.njk) -->
description: Коллекционные модели автомобилей разных стран
---

# {{ title }}

<p>Добро пожаловать на сайт коллекционных моделей автомобилей!</p>
<a href="blog/post-1/">Перейти к первому посту </a>
Файл главной страницы: index.md (src/index.md)
  1. Запустите сервер локально из директории, содержащей файл .eleventy.js, с помощью команды npm start. Чтобы остановить сервер, нажмите Ctrl+C.
  2. Создайте в папке src/includes/ макет post.njk, который будет использоваться для создания постов в блоге, и добавьте в него следующее:
{% extends "base.njk" %}  <!-- Наследуем базовый шаблон base.njk -->

{% block content %}
<article>
    <h1>{{ title }}</h1>
    <p>Автор: {{ author }}</p>
    <time>Дата публикации: {{ date | date('YYYY-MM-DD') }}</time>  <!-- date берется из front matter, и, если date нет - страница не создастся. -->
    <h2>Список автомобилей:</h2>
    <ul>
    {% for brand in brands %}
        <li>{{ brand }}</li>
    {% endfor %}
    </ul>
    {{ content | safe }}
</article>
{% endblock %}
Макет post.njk (src/includes/post.njk)

{% extends "base.njk" %} — команда указывает на наследование от родительского шаблона base.njk. Текущий шаблон становится дочерним и перенимает структуру base.njk. При этом можно переопределять отдельные блоки, сохраняя общую структуру. extends удобен для создания набора страниц с единым дизайном.

{{ date | date('YYYY-MM-DD') }} — переменная, обычно получаемая из Front Matter, которая содержит дату создания файла. В этом примере используется кастомный фильтр date(), добавленный в конфигурации Eleventy (файл .eleventy.js), для форматирования даты в нужном виде. YYYY-MM-DD — это шаблон форматирования, где:

{% for brand in brands %}<li>{{ brand }}</li>{% endfor %} — пример итерации (цикла) по списку данных (массиву). Цикл перебирает каждый элемент списка brands (значения берутся из Front Matter дочерней страницы, например, файла post-1.md), присваивает его переменной brand, которая затем используется для формирования HTML.

✒️ Черновики в Eleventy позволяют создавать и редактировать контент, не публикуя его сразу на сайте. По умолчанию, Eleventy ищет черновики в папке _drafts/.

Существует два способа опубликовать черновик:

---
published: true
---

published: false — флаг в Front Matter указывает Eleventy не включать страницу в финальную сборку сайта. Файл будет проигнорирован.


Метаданные (Front Matter)

✒️ Метаданные в Eleventy — это блок в начале файла, который содержит информацию о странице. Блок ограничен тремя дефисами (---) в начале и в конце и позволяет добавлять метаинформацию. Front Matter может быть в форматах YAML, JSON или JavaScript.

Данные в Front Matter имеют наивысший приоритет и переопределяют другие данные (например, значения по умолчанию в шаблонах), за исключением вычисляемых данных.

Создадим страницу первого поста:

  1. Для этого создайте папку blog внутри папки src/.
  2. Создайте файл post-1.md внутри src/blog/:
---
layout: post.njk
title: Легковые автомобили СССР
description: Коллекция легковых автомобилей СССР
author: frontrabotka
tags:
- posts
- sssr
- passenger
date: 2025-05-01
permalink: blog/post-1/
brands:
- Volga
- Moskvich
- Lada
---
<!-- Здесь будет текст статьи -->
Пост в блоге: файл post-1.md (src/blog/post-1.md)

layout: post.njk — указывает Eleventy использовать файл post.njk как макет.

tags: posts, sssr и passenger — указывает Eleventy, в какие коллекции включить данную страницу. Теги автоматически создают соответствующие коллекции (см. раздел «Коллекции»).

date: 2025-05-01 — переопределяет дату по умолчанию, для сортировки.

permalink: /blog/post-1/ — задаёт URL-адрес страницы. Если подкаталог blog не существует, он будет создан автоматически. Важно: если не указать имя файла и завершающий слэш (/), Eleventy создаст файл без расширения.

При permalink: false запись файла в выходную папку отключается. Файл обрабатывается, но не доступен в выходном каталоге. Это может быть полезно, например, для sitemap.

brands: Volga, Moskvich и Lada — это пользовательское поле данных, специфичное для этого поста. Если массив brands также определён в других местах, значения из Front Matter будут иметь приоритет. Данные для массива brands также возможно вынести в отдельный глобальный файл (brands.json) (см. раздел «Глобальные файлы данных»).


Файлы данных шаблонов (Template Data Files)

✒️ Файлы данных шаблонов в Eleventy — это отдельные файлы с данными, которые предназначены для использования в конкретном шаблоне. Они помогают отделить метаданные и конфигурацию от контента, делая структуру проекта более организованной.

Вместо написания ключей во Front Matter можно создать отдельный файл данных шаблона, предоставляющий данные для отдельного шаблона. Например, для файла post-1.md в папке blog/ можно создать файл post-1.json. Eleventy также поддерживает альтернативные имена: post-1.11tydata.json или post-1.11tydata.js.

{
  "layout": "post.njk",
  "title": "Легковые автомобили СССР",
  "description": "Коллекция легковых автомобилей СССР",
  "tags": [
    "posts",
    "sssr",
    "passenger"
  ],
  "author": "frontrabotka",
  "permalink": "blog/post-1/",
  "brands": [
    "Volga",
    "Moskvich",
    "Lada"
  ]
}
Файл post-1.json (src/blog/post-1.json)

Данные из файла автоматически доступны в шаблоне через переменные.

После создания файла данных шаблона, одинаковые поля следует удалить из Front Matter файла post-1.md:

---
date: 2025-05-01
---

<!-- Здесь будет текст статьи -->
Пост в блоге: файл post-1.md (src/blog/post-1.md)

В файле post-1.md остались только title, description, date, permalink и brands, так как остальные параметры (layout, tags, author) теперь определены в файле данных каталога blog.json.

Данные из файла данных шаблона автоматически объединятся с данными из Front Matter, при этом данные из Front Matter будут иметь приоритет.

Примечание I: в файле post-1.md я оставил ключ date, так как Eleventy выдавал ошибку при сборке, если date находился в файле post-1.json.

Примечание II: в случае проблемы с отображением страницы post-1.md после запуска локального сервера, попробуйте:

1. Удалить содержимое папки blog/ в выходной папке site/;

2. Перезапустить сервер.


Файлы данных каталога (Directory Data Files)

✒️ Файлы данных каталога в Eleventy задают данные, которые будут доступны всем шаблонам внутри определённой папки. Это упрощает централизованное управление метаданными для связанных файлов.

Файлы данных каталога позволяют создать общий файл с настройками, которые будут использоваться для всех шаблонов в данной папке (каталоге).

Создадим файл данных каталога для папки blog/:

  1. Удалите файл post-1.json из папки blog/. Если post-1.json останется, его данные переопределят данные из blog.json.
  2. Для папки blog/ создайте файл данных blog.json (Eleventy также поддерживает имена blog.11tydata.json или blog.11tydata.js). Важно, чтобы имя JSON-файла совпадало с именем папки, в которой он находится. В этом файле зададим значения по умолчанию для макета и другие ключи, которые применятся ко всем файлам в папке blog/:
{
  "layout": "post.njk",
  "tags": ["posts"],
  "author": "frontrabotka"
}
Файл blog.json (src/blog/blog.json)

"tags": ["posts"] — добавляет каждый файл в этой папке в коллекцию posts. Если в подпапках нет своих файлов данных каталога, то эти теги будут применяться и к файлам в этих подпапках.

Теперь эти данные (например, author, определённый в blog.json) доступны через переменные в любом шаблоне, расположенном в папке blog/. Для доступа к данным в шаблонах (например, в post.njk) используется синтаксис: {{ author }}.

  1. После создания файла данных каталога, измените файл post-1.md:
---
title: Легковые автомобили СССР
description: Коллекция легковых автомобилей СССР
date: 2025-05-01
permalink: blog/post-1/
brands:
- Volga
- Moskvich
- Lada
---
<!-- Здесь будет текст статьи -->
Пост в блоге: файл post-1.md (src/blog/post-1.md)

Примечание: в случае проблемы с отображением страницы post-1.md после запуска локального сервера, попробуйте:

1. Удалить содержимое папки blog/ в выходной папке site/;

2. Перезапустить сервер.


Глобальные файлы данных (Global Data Files)

✒️ Глобальные файлы данных в Eleventy — это файлы, которые содержат данные, доступные для всех шаблонов проекта. Данные размещаются в директории _data/ и могут быть в форматах JSON или JavaScript.

  1. Создадим папку _data в папке src/. Eleventy автоматически добавляет все .json файлы и значения module.exports из .js файлов, которые находятся в этой папке, в глобальный объект данных, доступный во всех шаблонах.
  2. В папке src/_data создадим файл brands.json с массивом строк, значения которого будет использовать страница первого поста — post-1.md:
[
  "Volga",
  "Moskvich",
  "Lada"
]
Файл brands.json (src/_data/brands.json)
  1. После создания файла brands.json удалите массив brands из Front Matter файла post-1.md, чтобы данные брались из brands.json:
---
title: Легковые автомобили СССР
description: Коллекция легковых автомобилей СССР
date: 2025-05-01
permalink: blog/post-1/
---
<!-- Здесь будет текст статьи -->
Пост в блоге: файл post-1.md (src/blog/post-1.md)

Теперь, чтобы получить доступ к данным из brands.json в шаблоне post.njk, используйте имя файла (без расширения) как имя переменной: {{ brands }}.


Коллекции (Collections)

✒️ Коллекции в Eleventy — это упорядоченные группы контента (например, страниц или постов), которые позволяют удобно работать с наборами связанных материалов на сайте. Коллекции автоматически упорядочиваются по дате создания и доступны во всех шаблонах проекта.

Коллекции позволяют объединять страницы со схожей тематикой или типом контента. Например, все записи блога можно объединить в коллекцию posts.

В Eleventy коллекции создаются двумя основными способами:

module.exports = function (eleventyConfig) {
    eleventyConfig.addCollection("posts", function (collectionApi) {
        return collectionApi.getFilteredByGlob("src/blog/*.md")
    })
}

Глоб-паттерн src/blog/*.md указывает Eleventy на необходимость включить в коллекцию posts все Markdown-файлы, которые находятся в папке src/blog/.

✒️ Глоб-паттерн (glob pattern) — это специальный шаблон для поиска файлов и директорий в системе.

Часть контента может быть частью нескольких коллекций, если указать несколько тегов в массиве tags в Front Matter. Выведем на главной странице список всех постов с тегом posts. Для этого в файле index.md добавим массив с объектом collections:

---
layout: base.njk
title: Игрушечные модели автомобилей
description: Коллекционные модели автомобилей разных стран
---

# {{ title }}

<h2>Последние записи в блоге:</h2>

{%- for post in collections.posts %}
  <article>
    <a href="{{ post.url | url }}">
      <h2>{{ post.data.title }}</h2>
    </a>
      <time>{{ post.data.date | date('YYYY-MM-DD') }}</time>
  </article>
{%- endfor %}
Файл главной страницы: index.md (src/index.md)

collections.posts — это массив, который содержит все страницы, которым присвоен тег posts.

Nunjucks отображает все символы, не входящие в выражения и операторы, буквально, включая пробелы. Символы -% (минус и процент) указывают Nunjucks, что нужно удалить пробелы в начале и конце блока.

Для работы с элементами коллекции в шаблонах доступны следующие свойства:

По умолчанию Eleventy сортирует контент в коллекциях по возрастанию даты (от старых к новым), используя следующие критерии:

  1. Значение поля date в Front Matter (если указано).
  2. Если поле date не указано, используется дата создания файла.
  3. При совпадении дат файлы сортируются по полному пути к входному файлу (включая имя файла).

Для изменения порядка сортировки по убыванию в шаблоне можно использовать фильтр | reverse:

{%- for post in collections.posts | reverse %}
  <article>
    <a href="{{ post.url | url }}">
      <h2>{{ post.data.title }}</h2>
    </a>
      <time>{{ post.data.date | date('YYYY-MM-DD') }}</time>
  </article>
{%- endfor %}

Фильтр | reverse инвертирует текущий порядок сортировки элементов коллекции, но не меняет критерий сортировки (например, по дате, по заголовку и т.д.).

Способ сортировки контента в коллекции можно изменить, изменив значение ключа date во Front Matter:

---
date: 2025-05-01
---

Eleventy автоматически включает весь контент (независимо от наличия тегов) в коллекцию collections.all. Эта коллекция позволяет перебрать все страницы сайта в шаблоне:

{%- for post in collections.all %}
  <article>
    <a href="{{ post.url | url }}">
      <h2>{{ post.data.title }}</h2>
    </a>
      <time>{{ post.data.date }}</time>
  </article>
{%- endfor %}

Пагинация (Pagination)

✒️ Пагинация в Eleventy — это способ автоматического создания нескольких страниц контента из одного шаблона на основе предоставленных данных. Это полезно для разделения больших коллекций контента (например, постов блога) на отдельные страницы, улучшая навигацию, производительность сайта и SEO.

Пагинация может работать с данными в форме массива или массива объектов, а также с коллекциями Eleventy.

Чтобы настроить пагинацию:

  1. Подготовьте данные для пагинации. В этом примере мы используем массив объектов с информацией об автомобилях, который расположен в файле brands.json (необходимо его изменить) в папке _data/:
[
  {
    "name": "Легковые автомобили СССР",
    "brands": [
      "Volga",
      "Moskvich",
      "Lada"
    ]
  },
  {
    "name": "Грузовые автомобили СССР",
    "brands": [
      "Gaz",
      "Kamaz",
      "Ural"
    ]
  },
  {
    "name": "Иностранные автомобили",
    "brands": [
      "Volvo",
      "Mercedes",
      "Opel"
    ]
  }
]
Файл brands.json (src/_data/brands.json)
  1. Создадим шаблон cars.njk, который будет использоваться для каждой страницы пагинации:
---
layout: base.njk
pagination:
  data: brands
  size: 1
  alias: car
permalink: "brands/{{ car.name | slugify }}/"
---

<h1>{{ car.name }}</h1>

<ul>
  {% for brand in car.brands %}
    <li>{{ brand }}</li>
  {% endfor %}
</ul>

<nav>
  {% if pagination.previous %}  <!-- Проверяем, есть ли предыдущая страница -->
    <a href="{{ pagination.previous | url }}">Предыдущая</a>  <!-- Если есть, показываем ссылку -->
  {% endif %}
  {% if pagination.next %}  <!-- Проверяем, есть ли следующая страница -->
    <a href="{{ pagination.next | url }}">Следующая</a>  <!-- Если есть, показываем ссылку --> 
  {% endif %}
</nav>
Шаблон cars.njk (src/cars.njk)

Примечание: После ключа pagination важно соблюдать отступы в строках для значений data, alias, size. Это связано с YAML-синтаксисом, который чувствителен к отступам. В противном случае Eleventy выдаст ошибку при сборке.

Важно, чтобы файл cars.njk (или шаблон, указанный в настройках пагинации) находился в папке src/. Иначе папка cars/ не сгенерируется.

Значение pagination во Frontmatter указывает Eleventy на необходимость создания нескольких страниц на основе данных, указанных в параметре data.

data: brands — указывает Eleventy, что нужно создать несколько страниц на основе данных из файла brands.json в папке _data/.

size: 1 — определяет количество элементов на каждой странице. Значение 1 означает, что каждая запись из brands.json создаст отдельную страницу. Если бы было 2, то страницы создавались бы по две записи на каждой.

alias: car — создаёт псевдоним для обращения к данным внутри шаблона. alias: car позволяет обращаться к данным каждой отдельной странице пагинации через переменную car. Это удобно, когда структура данных сложная и нужно избежать путаницы. Не рекомендуется использовать alias: page, так как page — это зарезервированное слово в Eleventy. Также зарезервированы pagination и collections.

permalink: "brands/{{ car.name | slugify }}/" — определяет структуру URL для каждой создаваемой страницы. {{ car.name }} выводит значение свойства name текущего объекта (автомобиля), к которому мы обращаемся по псевдониму car. Фильтр | slugify преобразует название в URL-friendly формат (например, «Легковые автомобили» → «legkovye-avtomobili»). Тогда будет создан файл index.html внутри папки legkovye-avtomobili: brands/legkovye-avtomobili/index.html.

Навигацию между страницами можно реализовать с помощью переменных, которые Eleventy предоставляет для пагинации:

В результате сборки сайта создадутся 3 страницы в папке brands/, и каждая страница будет содержать контент, сгенерированный на основе одной записи из brands.json:

Страницы сгенерированы, но пока не связаны с главной страницей. Чтобы добавить ссылки на эти страницы, измените файл index.md:

---
layout: base.njk
title: Игрушечные модели автомобилей
description: Коллекционные модели автомобилей разных стран
---

# {{ title }}

<h2>Категории автомобильных моделей:</h2>

<ul>
    <li><a href="{{ 'brands/legkovye-avtomobili-sssr/' | url }}">Легковые автомобили СССР</a></li>
    <li><a href="{{ 'brands/gruzovye-avtomobili-sssr/' | url }}">Грузовые автомобили СССР</a></li>
    <li><a href="{{ 'brands/inostrannye-avtomobili/' | url }}">Иностранные автомобили</a></li>
</ul>
Файл главной страницы: index.md (src/index.md)

Как альтернативу, можно использовать следующий permalink: "brands/page-{{ pagination.pageNumber }}/". Тогда каждая страница в папке brands/ будет иметь свой URL в формате:

Тогда файл index.md должен выглядеть так:

---
layout: base.njk
title: Игрушечные модели автомобилей
description: Коллекционные модели автомобилей разных стран
---

# {{ title }}

<h2>Категории автомобильных моделей:</h2>

<ul>
    <li><a href="{{ 'brands/page-0/' | url }}">Легковые автомобили СССР</a></li>
    <li><a href="{{ 'brands/page-1/' | url }}">Грузовые автомобили СССР</a></li>
    <li><a href="{{ 'brands/page-2/' | url }}">Иностранные автомобили</a></li>
</ul>
Файл главной страницы: index.md (src/index.md)

Нумерация страниц начинается с 0, так как pagination.pageNumber — это индекс текущей страницы в массиве данных.

Nunjucks позволяет изменить нумерацию страниц, начинающуюся с 0, на нумерацию с 1, добавив +1: permalink: "brands/page-{{ pagination.pageNumber + 1 }}/index.html".

Результирующие страницы с данными будут обновляться автоматически по мере добавления или редактирования записей в файле brands.json.


Каскад данных (Data Cascade)

✒️ Каскад данных в Eleventy — это система иерархической обработки данных, которая позволяет объединять информацию из разных источников в определённом порядке перед тем, как шаблон будет отрендерен. Чем ближе данные к контенту, тем выше их приоритет. Данные с более высокого уровня автоматически переопределяют данные с более низкого уровня.

Эта иерархия позволяет, например, задать общие настройки для всего сайта в глобальных файлах данных, переопределить их для конкретной папки в файлах данных каталога и затем переопределить отдельные параметры для конкретной страницы в Front Matter.

При объединении данных в каскаде данных в Eleventy порядок приоритета источников данных следующий (от наивысшего к низшему):

  1. Вычисляемые данные (Computed Data) — специальные функции, которые могут динамически вычислять значения.
  2. Метаданные (Front Matter) — данные из Front Matter текущего файла.
  3. Файлы данных шаблонов (Template Data Files) — данные из файла с таким же именем, как у шаблона.
  4. Файлы данных каталога (Directory Data Files) — данные из файла с таким же именем, как у папки.
  5. Метаданные в макетах (Front Matter in Layouts) — данные из Front Matter макета.
  6. Конфигурация API глобальных данных (Configuration API Global Data) — данные, добавленные через API.
  7. Глобальные файлы данных (Global Data Files) — данные из папки _data/.
Каскад данных в Eleventy
Каскад данных в Eleventy

Фильтры (Filters)

✒️ Фильтры в Eleventy — это функции JavaScript, которые принимают значения в шаблоне, обрабатывают их, а затем возвращают изменённый контент для отображения вместо оригинала. Фильтры применяются к значениям с помощью оператора |.

Универсальный фильтр url работает с pathPrefix (который задаётся в файле .eleventy.js) для корректной нормализации абсолютных путей. Это полезно, если сайт размещён на GitHub Pages, который часто находится в подкаталоге. Если pathPrefix не установлен, то фильтр url ничего не делает. Например, при pathPrefix: '/conspect' можно использовать фильтр url следующим образом:

<link rel="stylesheet" href="{{ '/css/style.css' | url }}">  <!-- В шаблоне -->
<link rel="stylesheet" href="/conspect/css/style.css">  <!-- В результате -->

Фильтр автоматически добавляет префикс ко всем путям в шаблонах, что важно при развёртывании сайта в подкаталоге. Пример создания ссылки на главную страницу сайта (при условии, что в .eleventy.js установлен pathPrefix, иначе фильтр не будет работать):

<a href="{{ '/' | url }}">Главная</a>  <!-- В шаблоне -->
<a href="/conspect/">Главная</a>  <!-- В результате -->

Фильтр slugify — инструмент для преобразования текста в формат URL-слагов. Он автоматически конвертирует любые строки в безопасные имена файлов или URL-пути. Например, после обработки следующего шаблона:

---
title: Легковые автомобили СССР
permalink: "/{{ title | slugify }}/"
---

Результатом преобразования будет создание файла index.html в папке legkovye-avtomobili-sssr/: /legkovye-avtomobili-sssr/index.html.

Фильтр slugify выполняет следующие преобразования:

✒️ URL-слаг (URL slug) — это часть веб-адреса, которая следует после доменного имени или подкаталога и отделяется косой чертой (/).


Плагины (Plugins)

✒️ Плагины для Eleventy — это расширения, которые добавляют новую функциональность в систему. Они подключаются в конфигурационном файле .eleventy.js перед последним оператором return и должны быть установлены через npm.

Плагин eleventy-plugin-syntaxhighlight предназначен для автоматической подсветки синтаксиса кода в Markdown-файлах при сборке сайта.

Установка плагина @11ty/eleventy-plugin-syntaxhighlight:

  1. Установите плагин: npm install --save-dev @11ty/eleventy-plugin-syntaxhighlight.
  2. Зарегистрируйте плагин в файле .eleventy.js:
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");

module.exports = function (eleventyConfig) {
    eleventyConfig.addPassthroughCopy('assets');
    eleventyConfig.addPassthroughCopy('**/*.jpg');

    eleventyConfig.addFilter("date", function (dateObj) {
        return dateObj.toLocaleDateString('ru-RU', {
            year: 'numeric',
            month: 'long',
            day: 'numeric'
        });
    });

    eleventyConfig.addPlugin(syntaxHighlight);  // Регистрация плагина подсветки синтаксиса

    return {
        dir: {
            input: "src",
            output: "site",
            includes: "includes",
            data: "_data"
        },
        templateFormats: [
            "md",
            "njk",
            "html",
        ],
        markdownTemplateEngine: 'njk',
        pathPrefix: '/conspect',
    };
};
Файл .eleventy.js

Для подсветки синтаксиса, код необходимо заключить в тройные обратные кавычки (```) с указанием языка программирования (например, javascript):

```js
const example = "Hello World";
console.log(example);
```

Если требуется подсветить и вывести код Nunjucks без обработки, используйте теги {% raw %}и {% endraw %}. Например:

{% raw %}
<body>
    <main>
        {% block content %}
            {{ content | safe }}
        {% endblock %}
    </main>
    {% include 'footer.njk' %}
</body>
{% endraw %}