Гайд по Eleventy
Дата последней правки:
Примечание: в примерах используется синтаксис шаблонизатора Nunjucks.
Начало работы
Eleventy предназначен для создания статических веб-сайтов, которые не требуют бэкенда, базы данных или серверного рендеринга. Сайт представляет собой набор готовых файлов, которые можно напрямую разместить на веб-хостинге. Eleventy также используется для создания сложных сайтов с помощью плагинов и API.
Поэтапная установка и запуск Eleventy:
- Скачайте и установите Node.js (требуется Node.js версии 18 или выше) и npm.
- Проверьте работоспособность:
node --version
— показывает версию Node.js;npm --version
— показывает версию npm;- При необходимости также можно обновить менеджер пакетов npm до последней версии глобально:
npm install -g npm@latest
.
- Создайте папку для будущего проекта (например, eleventy-project):
mkdir eleventy-project
. - Перейдите в эту папку:
cd eleventy-project
. Далее все команды в терминале следует вводить из этой папки. - Создайте и настройте файл package.json:
npm init -y
. - Установите 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 до последней версии. - Создайте конфигурационный файл .eleventy.js в корне проекта. В этом файле настраивается Eleventy.
- Создайте пустой файл .nojekyll в корне проекта. Это необходимо только при размещении сайта на GitHub Pages, чтобы предотвратить обработку сайта как проекта Jekyll (по умолчанию GitHub Pages использует Jekyll для генерации сайтов).
- Запустите локальный сервер разработки:
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.js используется для настройки различных аспектов сайта, таких как указание входных и выходных директорий, добавление поддержки разных шаблонизаторов, определение фильтров и шорткодов для обработки данных, а также подключение плагинов для расширения функциональности Eleventy.
Файл package.json необходим для управления зависимостями проекта, определения скриптов для запуска (например, для сборки или запуска сервера разработки) и отслеживания версий установленных пакетов. Этот файл позволяет воспроизвести среду разработки на любом компьютере.
Любые пути, перечисленные в файле .gitignore, исключаются из отслеживания системой контроля версий.
Папка node_modules хранит установленные через npm/yarn пакеты и их зависимости. Eleventy автоматически игнорирует эту папку.
✒️ Зависимость в программировании — это внешний компонент или библиотека, которую ваш проект использует для выполнения определённых задач.
Основные команды Eleventy:
npx @11ty/eleventy --serve
— запускает Eleventy в режиме разработки с автоматической перезагрузкой сайта при любых изменениях в файлах. Команда используется для локальной разработки и тестирования. Сайт можно посмотреть, если перейти по адресу, который указан в консоли после запуска команды.npm run build
— команда генерирует статический сайт и сохраняет его в папке _site (или в другой папке, указанной в настройках Eleventy). Полученную папку можно развернуть на любом веб-сервере.
Команды переопределяются в файле package.json:
{
"scripts": {
"start": "eleventy --serve",
// Запуск сервера разработки
"build": "cross-env ELEVENTY_ENV=production eleventy"
// Сборка проекта для релиза (production)
}
}
Теперь в терминале команда npm start
заменяет команду npx @11ty/eleventy --serve
.
Настройки
Все настройки проекта хранятся в файле .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
};
};
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: { ... }
— определяет структуру каталогов проекта.
input: 'src'
— указывает, что исходные файлы находятся в папке src;output: 'site'
— результат сборки сайта будет сохраняться в папку site;includes: 'includes'
— указывает папку для переиспользуемых компонентов (частей страниц) внутри входной директории (src). В этом случае компоненты должны находиться в папке src/includes;data: '_data'
— указывает папку для глобальных данных внутри входной директории (src). Глобальные данные должны находиться в папке src/_data.
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, не генерируют отдельные страницы, а используются как части других страниц: шаблоны, макеты, включаемые элементы.
Для начала создадим базовые шаблоны для проекта:
- Создайте папку includes (см. конфиг .eleventy.js) в папке src.
- Внутри папки 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>
{{ 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 %}
— определяет блок контента. Блоки используются для наследования шаблонов: дочерние шаблоны могут переопределять содержимое блоков, определённых в родительском шаблоне.
{% block content %}
— начало блока.{% endblock %}
— конец блока.
{{ content | safe }}
— во время сборки Eleventy автоматически вставляет сюда содержимое из Markdown-файлов и других источников данных. Фильтр | safe
отключает автоматическое экранирование HTML, позволяя выводить HTML-контент без изменений.
Создадим шаблон «подвала» сайта в папке src/includes/ — footer.njk:
<p>© 2025</p>
Макеты (Layouts)
✒️ Макет — это шаблон, определяющий общую структуру страницы, в которую «оборачивается» содержимое других шаблонов.
Макеты придают нескольким шаблонам одинаковую базовую структуру.
Согласно настройкам в .eleventy.js, Eleventy ищет макеты в папке src/includes/.
Создадим дополнительные страницы сайта:
- Создайте в папке src/ файл index.md. Это будет главная страница сайта:
---
layout: base.njk <!-- Указываем макет base.njk -->
title: Игрушечные модели автомобилей <!-- Этот заголовок будет отображён в теге <title> (см. base.njk) -->
description: Коллекционные модели автомобилей разных стран
---
# {{ title }}
<p>Добро пожаловать на сайт коллекционных моделей автомобилей!</p>
<a href="blog/post-1/">Перейти к первому посту </a>
- Запустите сервер локально из директории, содержащей файл .eleventy.js, с помощью команды
npm start
. Чтобы остановить сервер, нажмите Ctrl+C. - Создайте в папке 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 %}
{% extends "base.njk" %}
— команда указывает на наследование от родительского шаблона base.njk. Текущий шаблон становится дочерним и перенимает структуру base.njk. При этом можно переопределять отдельные блоки, сохраняя общую структуру. extends
удобен для создания набора страниц с единым дизайном.
{{ date | date('YYYY-MM-DD') }}
— переменная, обычно получаемая из Front Matter, которая содержит дату создания файла. В этом примере используется кастомный фильтр date()
, добавленный в конфигурации Eleventy (файл .eleventy.js), для форматирования даты в нужном виде. YYYY-MM-DD
— это шаблон форматирования, где:
YYYY
— год в формате 2025;MM
— месяц в формате 01-12;DD
— день в формате 01-31.
{% for brand in brands %}<li>{{ brand }}</li>{% endfor %}
— пример итерации (цикла) по списку данных (массиву). Цикл перебирает каждый элемент списка brands
(значения берутся из Front Matter дочерней страницы, например, файла post-1.md), присваивает его переменной brand
, которая затем используется для формирования HTML.
✒️ Черновики в Eleventy позволяют создавать и редактировать контент, не публикуя его сразу на сайте. По умолчанию, Eleventy ищет черновики в папке _drafts/.
Существует два способа опубликовать черновик:
- Переместить файл из директории _drafts/ в «публичную» директорию (например, src/ или другую).
- Использовать флаг
published: false
в Frontmatter и изменить его наtrue
:
---
published: true
---
published: false
— флаг в Front Matter указывает Eleventy не включать страницу в финальную сборку сайта. Файл будет проигнорирован.
Метаданные (Front Matter)
✒️ Метаданные в Eleventy — это блок в начале файла, который содержит информацию о странице. Блок ограничен тремя дефисами (---
) в начале и в конце и позволяет добавлять метаинформацию. Front Matter может быть в форматах YAML, JSON или JavaScript.
Данные в Front Matter имеют наивысший приоритет и переопределяют другие данные (например, значения по умолчанию в шаблонах), за исключением вычисляемых данных.
Создадим страницу первого поста:
- Для этого создайте папку blog внутри папки src/.
- Создайте файл 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
---
<!-- Здесь будет текст статьи -->
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"
]
}
Данные из файла автоматически доступны в шаблоне через переменные.
После создания файла данных шаблона, одинаковые поля следует удалить из Front Matter файла post-1.md:
---
date: 2025-05-01
---
<!-- Здесь будет текст статьи -->
В файле 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/:
- Удалите файл post-1.json из папки blog/. Если post-1.json останется, его данные переопределят данные из blog.json.
- Для папки blog/ создайте файл данных blog.json (Eleventy также поддерживает имена blog.11tydata.json или blog.11tydata.js). Важно, чтобы имя JSON-файла совпадало с именем папки, в которой он находится. В этом файле зададим значения по умолчанию для макета и другие ключи, которые применятся ко всем файлам в папке blog/:
{
"layout": "post.njk",
"tags": ["posts"],
"author": "frontrabotka"
}
"tags": ["posts"]
— добавляет каждый файл в этой папке в коллекцию posts. Если в подпапках нет своих файлов данных каталога, то эти теги будут применяться и к файлам в этих подпапках.
Теперь эти данные (например, author
, определённый в blog.json) доступны через переменные в любом шаблоне, расположенном в папке blog/. Для доступа к данным в шаблонах (например, в post.njk) используется синтаксис: {{ author }}
.
- После создания файла данных каталога, измените файл post-1.md:
---
title: Легковые автомобили СССР
description: Коллекция легковых автомобилей СССР
date: 2025-05-01
permalink: blog/post-1/
brands:
- Volga
- Moskvich
- Lada
---
<!-- Здесь будет текст статьи -->
Примечание: в случае проблемы с отображением страницы post-1.md после запуска локального сервера, попробуйте:
1. Удалить содержимое папки blog/ в выходной папке site/;
2. Перезапустить сервер.
Глобальные файлы данных (Global Data Files)
✒️ Глобальные файлы данных в Eleventy — это файлы, которые содержат данные, доступные для всех шаблонов проекта. Данные размещаются в директории _data/ и могут быть в форматах JSON или JavaScript.
- Создадим папку _data в папке src/. Eleventy автоматически добавляет все .json файлы и значения
module.exports
из .js файлов, которые находятся в этой папке, в глобальный объект данных, доступный во всех шаблонах. - В папке src/_data создадим файл brands.json с массивом строк, значения которого будет использовать страница первого поста — post-1.md:
[
"Volga",
"Moskvich",
"Lada"
]
- После создания файла brands.json удалите массив
brands
из Front Matter файла post-1.md, чтобы данные брались из brands.json:
---
title: Легковые автомобили СССР
description: Коллекция легковых автомобилей СССР
date: 2025-05-01
permalink: blog/post-1/
---
<!-- Здесь будет текст статьи -->
Теперь, чтобы получить доступ к данным из brands.json в шаблоне post.njk, используйте имя файла (без расширения) как имя переменной: {{ brands }}
.
Коллекции (Collections)
✒️ Коллекции в Eleventy — это упорядоченные группы контента (например, страниц или постов), которые позволяют удобно работать с наборами связанных материалов на сайте. Коллекции автоматически упорядочиваются по дате создания и доступны во всех шаблонах проекта.
Коллекции позволяют объединять страницы со схожей тематикой или типом контента. Например, все записи блога можно объединить в коллекцию posts.
В Eleventy коллекции создаются двумя основными способами:
- Через Front Matter: добавьте поле
tags
в Front Matter файла. Значениеtags
может быть строкой или массивом строк, указывающих, к каким коллекциям принадлежит данный контент. Теги (tags
) в Eleventy используются только для создания коллекций. - Через файл конфигурации .eleventy.js:
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 %}
collections.posts
— это массив, который содержит все страницы, которым присвоен тег posts.
Nunjucks отображает все символы, не входящие в выражения и операторы, буквально, включая пробелы. Символы -%
(минус и процент) указывают Nunjucks, что нужно удалить пробелы в начале и конце блока.
Для работы с элементами коллекции в шаблонах доступны следующие свойства:
post.url
— URL страницы;post.data
— данные из Front Matter;post.content
— содержимое страницы.
По умолчанию Eleventy сортирует контент в коллекциях по возрастанию даты (от старых к новым), используя следующие критерии:
- Значение поля
date
в Front Matter (если указано). - Если поле
date
не указано, используется дата создания файла. - При совпадении дат файлы сортируются по полному пути к входному файлу (включая имя файла).
Для изменения порядка сортировки по убыванию в шаблоне можно использовать фильтр | 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.
Чтобы настроить пагинацию:
- Подготовьте данные для пагинации. В этом примере мы используем массив объектов с информацией об автомобилях, который расположен в файле brands.json (необходимо его изменить) в папке _data/:
[
{
"name": "Легковые автомобили СССР",
"brands": [
"Volga",
"Moskvich",
"Lada"
]
},
{
"name": "Грузовые автомобили СССР",
"brands": [
"Gaz",
"Kamaz",
"Ural"
]
},
{
"name": "Иностранные автомобили",
"brands": [
"Volvo",
"Mercedes",
"Opel"
]
}
]
- Создадим шаблон 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>
Примечание: После ключа 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 предоставляет для пагинации:
pagination.previous
— ссылка на предыдущую страницу;pagination.next
— ссылка на следующую страницу;pagination.items
— массив ссылок на все страницы пагинации;pagination.pageNumber
— номер текущей страницы;pagination.pageSize
— размер страницы;pagination.totalPages
— общее количество страниц.
В результате сборки сайта создадутся 3 страницы в папке brands/, и каждая страница будет содержать контент, сгенерированный на основе одной записи из brands.json:
- gruzovye-avtomobili-sssr/index.html
- inostrannye-avtomobili/index.html
- legkovye-avtomobili-sssr/index.html
Страницы сгенерированы, но пока не связаны с главной страницей. Чтобы добавить ссылки на эти страницы, измените файл 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>
Как альтернативу, можно использовать следующий permalink: "brands/page-{{ pagination.pageNumber }}/"
. Тогда каждая страница в папке brands/ будет иметь свой URL в формате:
- page-0/index.html
- page-1/index.html
- page-2/index.html
Тогда файл 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>
Нумерация страниц начинается с 0, так как pagination.pageNumber
— это индекс текущей страницы в массиве данных.
Nunjucks позволяет изменить нумерацию страниц, начинающуюся с 0, на нумерацию с 1, добавив +1
: permalink: "brands/page-{{ pagination.pageNumber + 1 }}/index.html"
.
Результирующие страницы с данными будут обновляться автоматически по мере добавления или редактирования записей в файле brands.json.
Каскад данных (Data Cascade)
✒️ Каскад данных в Eleventy — это система иерархической обработки данных, которая позволяет объединять информацию из разных источников в определённом порядке перед тем, как шаблон будет отрендерен. Чем ближе данные к контенту, тем выше их приоритет. Данные с более высокого уровня автоматически переопределяют данные с более низкого уровня.
Эта иерархия позволяет, например, задать общие настройки для всего сайта в глобальных файлах данных, переопределить их для конкретной папки в файлах данных каталога и затем переопределить отдельные параметры для конкретной страницы в Front Matter.
При объединении данных в каскаде данных в Eleventy порядок приоритета источников данных следующий (от наивысшего к низшему):
- Вычисляемые данные (Computed Data) — специальные функции, которые могут динамически вычислять значения.
- Метаданные (Front Matter) — данные из Front Matter текущего файла.
- Файлы данных шаблонов (Template Data Files) — данные из файла с таким же именем, как у шаблона.
- Файлы данных каталога (Directory Data Files) — данные из файла с таким же именем, как у папки.
- Метаданные в макетах (Front Matter in Layouts) — данные из Front Matter макета.
- Конфигурация API глобальных данных (Configuration API Global Data) — данные, добавленные через API.
- Глобальные файлы данных (Global Data Files) — данные из папки _data/.
Фильтры (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:
- Установите плагин:
npm install --save-dev @11ty/eleventy-plugin-syntaxhighlight
. - Зарегистрируйте плагин в файле .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',
};
};
Для подсветки синтаксиса, код необходимо заключить в тройные обратные кавычки (```
) с указанием языка программирования (например, 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 %}