Гайд по Nunjucks
Дата последней правки:
Примечание: если WebStorm не обнаруживает файлы Nunjucks, установите плагин TWIG.
Введение
Nunjucks — это движок шаблонов для JavaScript и Node.js, который позволяет создавать динамические веб-страницы путём разделения логики и представления. Он работает как препроцессор, преобразующий шаблоны и данные в готовый HTML-код.
Nunjucks позволяет вставлять содержимое одного файла в другой. Это даёт возможность выносить в отдельные файлы разметку повторяющихся блоков.
✒️ Препроцессор — это специальный инструмент, который преобразует и расширяет исходный код из одного формата в другой перед выполнением или компиляцией.
Переменные
✒️ Переменные в Nunjucks — это именованные контейнеры для хранения значений, которые можно использовать в шаблоне. Nunjucks ищет значение переменной в контексте шаблона, который обычно содержит данные, переданные из приложения. Часто возникает ситуация, когда одни и те же данные выводятся в разных местах сайта, например, контактные данные или заголовок страницы. Для этого используются переменные, которые позволяют задавать значения в начале кода и выводить их в нужных участках.
Переменные создаются и присваиваются с использованием тега {% set %}
. Для вывода содержимого переменной используются двойные фигурные скобки {{ имяПеременной }}
:
{% set pageTitle = 'Главная страница' %}
{{ pageTitle }}
Вывод кода будет: «Главная страница».
Переменные доступны только после их объявления. По умолчанию они работают внутри текущего шаблона. Имена переменных могут содержать точку (.
), которая используется для доступа к свойствам объекта:
{{ post.url }}
Также можно использовать синтаксис квадратных скобок:
{{ post ['url'] }}
Если значение равно undefined
или null
, то ничего не отобразится.
Можно задавать несколько переменных одновременно:
{% set x = 1, y = 2, z = 3 %}
Если set
используется вне блоков с областью видимости (таких как блоки, определяемые include
, block
или macro
), он изменяет значение в контексте текущего шаблона и шаблонов, которые он включает. Если set
используется внутри блоков с областью видимости, таких как include
, то он изменяет только текущую область видимости.
Типы данных в Nunjucks:
- Строки:
{% set name = 'Волга' %}
; - Числа:
{% set age = 5 %}
; - Булевы значения:
{% set isAdmin = true %}
; - Массивы:
{% set cars = ['Волга', 'Лада'] %}
; - Объекты:
{% set user = { name: 'Иван', age: 30 } %}
.
Теги
✒️ Теги в Nunjucks — это специальные конструкции, используемые для контроля потока выполнения шаблона, реализации логики и организации структуры документа. Они являются основным строительным блоком для создания динамических шаблонов. Nunjucks использует синтаксис {%...%}
для управляющих операторов, таких как циклы, условные операторы и объявления переменных. Например:
<ul>
{% for brand in brands %}
<li>{{ brand }}</li>
{% endfor %}
</ul>
Nunjucks также предоставляет механизм для наследования шаблонов. Блоки, определяемые с помощью тега {% block %}
, представляют собой именованные участки в шаблонах, которые можно переопределить в дочерних шаблонах, реализуя таким образом механизм наследования и повторного использования кода. Как правило, есть открывающая часть {% block blockName %}
и закрывающая {% endblock %}
.
Чтобы вывести какой-либо из специальных тегов Nunjucks, можно заключить их внутри тега {% raw %}...{% endraw %}
. Всё, что находится внутри него, будет выведено как обычный текст. Это полезно при документировании или создании учебных материалов по Nunjucks:
{% raw %}
{% if true %}
{{ 'Добро пожаловать' }}
{% endif %}
{% endraw %}
Результатом будет:
{% if true %}
{{ 'Добро пожаловать' }}
{% endif %}
Когда Nunjucks обрабатывает шаблоны, он не удаляет переносы строк и пробелы вокруг тегов. Символ минус (-
) добавляется внутри тега, сразу после открывающей скобки {%-
для удаления пробелов слева или перед закрывающей скобкой -%}
для удаления пробелов справа:
{% for i in [1, 2, 3, 4, 5] -%}
{{ i }}
{%- endfor%}
Вывод этого кода будет: «12345».
То же самое касается переменных: {{-
удалит пробелы перед переменной, а -}}
удалит пробелы после переменной. Удаление пробелов работает и для других тегов (условия, макросы и т.д.).
Комментарии используются для добавления примечаний или пояснений к коду, которые игнорируются шаблонизаторами и не отображаются на странице: {# комментарий #}
.
Условия
✒️ Условия в Nunjucks — это механизм управления потоком выполнения шаблона, позволяющий отображать разный контент в зависимости от определённых условий. Это позволяет создавать динамические шаблоны, которые адаптируются под различные данные и ситуации, например, отображать разный контент для авторизованных и неавторизованных пользователей.
Условные операторы, такие как if
, elif
и else
, позволяют выполнять различные действия в зависимости от определённых условий.
Условный оператор if
проверяет условие и выборочно отображает содержимое:
{% if variable %}
Это верно
{% endif %}
Если переменная определена и оценивается как true (в Nunjucks это, например, непустая строка, число не равное 0, или логическое true), то будет отображено «Это верно». Иначе ничего не будет отображено.
Также есть возможность указать альтернативные условия с помощью конструкций elif
и else
:
{% if page == 'home' %}
Контент для главной страницы
{% elif page == 'contact' %}
Контент для страницы контактов
{% else %}
Контент для остальных страниц
{% endif %}
Предполагается, что page
— это переменная, доступная в Nunjucks шаблоне, которая содержит строку с названием страницы (например, home
, contact
).
Если значение переменной page
равно home
, то будет показан контент для главной страницы. Если значение равно contact
, будет показан контент для страницы контактов. Во всех остальных случаях будет показан общий контент.
{% if page == 'home' %}
проверяет первое условие.{% elif page == 'contact' %}
проверяет второе условие, если первое не выполнилось.{% else %}
выполняется, если ни одно из предыдущих условий не оказалось истинным.{% endif %}
завершает условное выражение.
Оператор ==
(равно) сравнивает два значения на равенство.
Оператор !=
(не равно) сравнивает два значения на неравенство.
Операторы сравнения: >
(больше), <
(меньше), >=
(больше или равно), <=
(меньше или равно).
Можно указать несколько условий с помощью and
и or
:
{% if happy and hungry %}
Я счастлив и голоден; оба условия верны
{% endif %}
{% if happy or hungry %}
Я счастлив или голоден; верно хотя бы одно из условий
{% endif %}
Оператор and
: оба условия должны быть истинными, чтобы результат был истинным. Например: {% if 1 == 1 and 2 == 2 %}
(истинно, так как оба условия истинны).
Оператор or
: хотя бы одно из условий должно быть истинным, чтобы результат был истинным. Например: {% if 1 == 1 or 2 == 3 %}
(истинно, так как первое условие истинно).
Операторы and
и or
работают в соответствии с законами логики. Порядок вычисления условий определяется приоритетом операторов (and
имеет более высокий приоритет, чем or
), но его можно изменить с помощью скобок.
Циклы
✒️ Циклы в Nunjucks — это механизм для повторяющегося выполнения блока кода над коллекцией данных (массивами, объектами или другими перебираемыми структурами). Они позволяют автоматически генерировать повторяющиеся части шаблона.
В Nunjucks для организации циклов используется конструкция for...in
(или просто for
), которая, как и в JavaScript, предназначена для перебора элементов массива или свойств объекта. При работе с массивами цикл перебирает элементы, которые затем можно использовать для доступа к их свойствам:
{% set brands = [
{ brand: 'Lada', country: 'USSR' },
{ brand: 'BMW', country: 'Germany' }
] %}
{% for item in brands %}
<p>Модель: {{ item.brand }}; Страна: {{ item.country }}</p>
{% endfor %}
Вывод кода будет:
<p>Модель: Lada; Страна: USSR</p>
<p>Модель: BMW; Страна: Germany</p>
В этом примере перечислены все элементы, используя атрибуты brand
и country
каждого элемента в массиве brands
. Оператор for
проходит по списку и выполняет действие для каждого элемента.
Также можно итерироваться по диапазону чисел:
{% for i in range(0, 5) %}
<p>Номер: {{ i }}</p>
{% endfor %}
Для данного примера Nunjucks выведет следующий HTML:
<p>Номер: 0</p>
<p>Номер: 1</p>
<p>Номер: 2</p>
<p>Номер: 3</p>
<p>Номер: 4</p>
Внутри цикла доступны специальные переменные:
loop.index
: Текущий индекс цикла (начинается с 1).loop.first: true
, если это первая итерация цикла.loop.last: true
, если это последняя итерация цикла.
Наследование шаблонов
Наследование шаблонов помогает создавать согласованную структуру веб-сайта, позволяя повторно использовать базовый шаблон и настраивать определённые части для разных страниц. Например, заголовок и футер страницы обычно имеют одинаковое содержимое на всех страницах. Поэтому нет смысла дублировать их везде, вместо этого можно определить их в одном файле и использовать его на всех страницах.
extends
используется для указания наследования шаблона. Указанный шаблон используется как базовый:
{% extends 'base.html' %}
С помощью include
можно вставлять повторно используемые компоненты или частичные шаблоны в основные шаблоны:
{% include 'header.html' %}
Эта функция помогает поддерживать согласованную структуру на сайте и избегать повторения кода. Важно отметить, что include
просто вставляет содержимое одного файла в другой, без какой-либо логики наследования или переопределения блоков.
Использование include
и наследование шаблонов соответствуют принципу DRY (Don't Repeat Yourself — не повторяйся). Идея состоит в том, что если нужно написать код более одного раза в нескольких местах, то его следует поместить в функцию.
block
определяет раздел в шаблоне и идентифицирует его с помощью имени. Это используется при наследовании шаблонов. Базовые шаблоны могут указывать блоки, а дочерние шаблоны могут переопределять их новым содержимым:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Мой сайт{% endblock %}</title>
{% block css %}
<link rel="stylesheet" href="main.css"/>
{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends 'base.html' %}
{% block title %}Главная страница{% endblock %}
{% block content %}
<h1>Добро пожаловать!</h1>
<p>Это главная страница сайта.</p>
{% endblock %}
В этом примере index.html наследует от base.html и переопределяет блоки title
и content
. Блок css
наследуется из base.html.
Фильтры
✒️ Фильтры в Nunjucks — это функции, которые применяются к переменным для преобразования или форматирования их значений перед отображением. Фильтры указываются после символа вертикальной черты (|
) и позволяют модифицировать данные перед выводом в шаблоне.
Например, с помощью фильтра upper
можно перевести текст в верхний регистр перед его выводом на страницу:
<h1>{{ 'Conspect' | upper }}</h1> <!-- код в шаблоне Nunjucks -->
<h1>CONSPECT</h1> <!-- результирующий HTML -->
Фильтры можно встраивать в цепочки для последовательной обработки данных:
{{ "mOdEl" | replace ('mOdEl', 'BrAnD') | capitalize }}
Этот код выведет «Brand», сначала заменив mOdEl
на BrAnD
, а затем сделав первую букву заглавной.
Если в среде включено автоматическое экранирование, то весь вывод будет автоматически экранироваться для безопасного отображения. Чтобы вручную пометить вывод как безопасный, можно использовать фильтр safe
. Nunjucks не будет экранировать этот вывод:
{{ brand }} <!-- Вывод: &amp;lt;span&amp;gt; -->
{{ brand | safe }} <!-- Вывод: <span> -->
Если автоэкранирование отключено, то весь вывод будет отображаться как есть.
Фильтр safe
следует использовать с осторожностью, поскольку он отключает экранирование и может привести к XSS-уязвимостям, если значение переменной получено из ненадёжного источника (например, от пользователя).
Можно вручную экранировать переменные с помощью фильтра escape
. Фильтр преобразует символы &
, <
, >
и "
в HTML-безопасные последовательности. Это полезно, если нужно отобразить текст, который может содержать HTML-символы, а также для предотвращения HTML-инъекций. Возвращаемое значение интерпретируется как строка разметки:
{{ brand }} <!-- Вывод: <span> -->
{{ brand | escape }} <!-- Вывод: &amp;lt;span&amp;gt; -->
✒️ HTML-инъекция — это тип уязвимости веб-приложений, который позволяет злоумышленнику внедрить произвольный HTML-код в веб-страницу, отображаемую другим пользователям. Это происходит, когда веб-приложение принимает данные от пользователя (например, через форму, URL-параметр или cookie) и включает эти данные в HTML-код страницы без должной проверки и экранирования.
Фильтр abs
возвращает абсолютное значение аргумента:
{{ -3 | abs }}
Вывод кода будет: «3».
Фильтр capitalize
делает первую букву заглавной, а остальные строчными:
{{ CoLLEctions | capitalize }}
Вывод кода будет: «Collections».
Фильтр lower
преобразует строку в нижний регистр:
{{ COLLECTIONS | lower }}
Вывод кода будет: «collections».
Фильтр random
выбирает случайное значение из массива (оно будет меняться при каждом обновлении страницы):
{{ [1,2,3,4,5,6] | random }}
Вывод кода будет: случайное значение от 1 до 6 включительно.
Фильтр reverse
переворачивает строку или массив:
{{ abcdef | reverse }}
Вывод кода будет: «fedcba». А чтобы перевернуть массив:
{% for i in [1, 2, 3, 4] | reverse %}
{{ i }}
{% endfor %}
В этом примере цикл for
будет итерироваться в обратном порядке: «4, 3, 2, 1».
Фильтр title
делает первую букву каждого слова заглавной:
{{ collections car germany | title }}
Вывод кода будет: «Collections Car Germany».
Фильтр upper
преобразует строку в верхний регистр:
{{ ussr | upper }}
Вывод кода будет: «USSR».