Теги
Описание всех доступных тегов шаблонного движка JuniperBot
Теги — набор различных встроенных конструкций и операций над шаблоном. Они объявляются с помощью островков кода и определяют поведение шаблона.
Команды#
Теги команд выполняют какую-либо операцию, но ничего не печатают в результат шаблона.
set
#
Команда set
является операцией присваивания переменной в шаблоне. Она вычислит результат выражения и запишет его в переменную с указанным названием:
{% set five = 2 + 3 %}
В примере выше результат вычисления 2 + 3
(5
) будет записан в переменную five
.
Команда set
также поддерживает составные операторы присваивания, используя основные логические операторы для арифметических операций (+
, -
, *
, **
, /
, //
) и объединения строк (~
):
{% set value = 2 %}
{% set value += 3 %}
В примере выше результирующее значение переменной будет равно 5.
Название переменной является идентификатором и может содержать только латинские буквы, цифры и нижнее подчеркивание, но не может начинаться с цифры.
set
как команда не генерирует контент, она просто объявляет переменную или перезаписывает существующую переменную с этим именем.
global
#
Эта команда аналогична команде set
, но присваивает эту переменную глобально. Это значит, что эта переменная будет доступна в последующих интерпретируемых шаблонах этого сообщения, в макросах и в действии, вызываемом через run
. Например, переменная, определенная глобальной в шаблоне сообщения станет сразу доступна в шаблоне панели.
{% global six = 3 + 3 %}
В примере выше результат вычисления 3 + 3
(6
) будет записан в переменную six
и доступен глобально.
do
#
Команда do
вычисляет указанное выражение, не печатая ничего в шаблон.
{% do something.run() %}
Поскольку вывод команды пуст, она может быть полезна для тихого вызова каких-либо функций у объектов.
require
#
Команда require
является расширением команды return
и выглядит следующим образом:
{% require выражение returning 'Произошла какая-то ошибка' %}
Эта команда вернет ошибку если результат вычисления выражения будет равен:
null
;undefined
;false
;- пустая строка;
0
.
Вместо строки можно передать заполненный Embed (но НЕ отправляя его функцией send
).
use
#
Команда use
включает дополнительную функциональность шаблонного движка или меняет его поведение.
strict#
Выполнение шаблона в строгом режиме. Это означает, что шаблонный движок будет возвращать ошибку компиляции в следующих случаях:
- Попытка вывести неопределённую переменную;
- Попытка обратиться к несуществующему свойству объекта;
- Попытка вызвать несуществующую функцию объекта или с некорректно переданными в неё аргументами.
Строгий режим включается следующим образом:
{% use 'strict' %}
run
#
Команда run
используется для запуска указанного Действия с передачей в него параметров (опционально).
Эта операция полностью прервёт текущее выполняемое действие.
Внимание
Данный тег работает только в Действиях пользовательских команд для "маршрутизации" одного действия в другое.
Используйте UUID действия для его запуска:
{% run 'aebf9ae8-c62a-4348-b153-a7c0a0173da1' %}
Информация
Вы можете получить этот UUID из самого действия в настройках команды (нажмите иконку "i"). Оба действия должны быть частью одной команды, т.е. действие команды А не может быть запущено из действия команды Б.
Для передачи параметров в запускаемое действие используйте следующий синтаксис:
{% run 'aebf9ae8-c62a-4348-b153-a7c0a0173da1' with { 'param1': 123 } %}
with
на самом деле просто карта, поэтому можно указать там объявленную ранее переменную карты.
Эти параметры будут доступны как часть переменной parameters в запускаемом действии:
{{ parameters.param1 }}
123
в запускаемом действии.
Вы также можете использовать сам parameters в родительском действии для передачи данных в дочернее. Следующий пример сделает абсолютно то же самое, как и предыдущий, просто другим способом:
{% do parameters.store('param1', 123) %}
{% run 'aebf9ae8-c62a-4348-b153-a7c0a0173da1' %}
Внимание
Действия могут запускать друг друга цепочкой до трёх раз. Квоты методов при этом остаются общие для всей цепочки.
Управляющие конструкции#
Шаблонный движок JuniperBot реализует базовые управляющие конструкции: условия и циклы
Условия — if/elseif/else
#
Условие — самая простая управляющая конструкция. Здесь поддерживаются последовательные конструкции с помощью оператора elseif
и конструкция else
.
{% if (выражение) %}
... Блок вычисляется если "выражение" вычислено как true ...
{% elseif (другоеВыражение) %}
... Блок вычисляется если "другоеВыражение" вычислено как true,
а так же "выражение" вычислено как false ...
{% else %}
... Блок вычисляется если ни одно из
указанных условий не было удовлетворено ...
{% endif %}
Обратите внимание, что конструкция if
выведет содержимое только первого блока, которое удовлетворяет объявленным условиям (то есть оценивается как true
). Способ, которым шаблонный движок оценивает выражение как true
, описан в статье Конвертация типов.
С точки зрения области видимости переменных, внутреннее содержимое блока if
разделяет контекст с родительским контекстом. Это означает, что условия могут влиять на переменные во внешней области видимости.
{% set variable = "раз" %}
{% if (true) %}
{% set variable = "два" %}
{% endif %}
{{ variable }}
Предыдущий пример генерирует сообщение два
, что иллюстрирует как область видимости в условиях разделяет контекст с родительской конструкцией.
{% if (1 != 2) %}
{% return 'Один не равен двум. Внезапно!' %}
{% endif %}
А вот этот текст шаблон не выведет из-за ошибки.
Пример выше демонстрирует, как можно с помощью условия вернуть ошибку.
Циклы — for
#
Поддерживаются циклы над списками или картами.
{% for item in list %}
... Контент с использованием переменной item ...
{% endfor %}
{% for key, value in map %}
... Контент с использованием переменных key и value карты ...
{% endfor %}
Переменная loop
#
Циклы for
объявляют дополнительную переменную с идентификатором loop
. Она предоставляет доступ к полезным свойствам внутри цикла:
Свойство | Описание |
---|---|
length |
Размер списка или карты |
index |
Номер текущей итерации, начинающийся с 1 |
index0 |
Номер текущей итерации, начинающийся с 0 |
revindex |
Количество оставшихся итераций до достижения конца списка или карты, заканчивается на 1 |
revindex0 |
Количество оставшихся итераций до достижения конца списка или карты, заканчивается на 0 |
first |
Свойство, равное true для самой первой итерации |
last |
Свойство, равное true для самой последней итерации |
parent |
Получение доступа к родительскому контексту |
{% for item in [1, 2, 3] %}
{% if (loop.first) %}
Начало
{% endif %}
{% endfor %}
Предыдущий пример распечатает слово Начало
только один раз во время первой итерации.
Переменная loop
привязана в контексту цикла for
, это значит, что область видимости этой переменной ограничена лишь содержимым блока цикла. Если вне цикла объявлена переменная с названием loop
, она не будет перезаписана, но доступ к ней можно будет получить только через родительский контекст, например:
{% set loop = 1 %}
{% for item in [1, 2, 3] %}
{% if (loop.first) %}
{{ loop.parent.loop }}
{% set loop = 2 %}
{% endif %}
{% endfor %}
{{ loop }}
Предыдущий пример распечатает 1 2
. Обратите внимание, что присваивание значения переменной loop
внутри цикла не перезаписывает loop
самого цикла. Эта переменная далее будет доступна уже вне цикла.
Трансформации — transform
#
Трансформация - разновидность цикла for
, используемая для преобразования одного списка в другой.
Каждая итерация такого цикла ожидает вызов тега return
с указанием нового значения для соответствующего элемента списка:
{% transform item in [1, 2, 3] as newList %}
{% return 'element:' ~ item %}
{% endtransform %}
{{ newList }}
Предыдущий пример преобразует список [1, 2, 3]
в ['element:1', 'element:2', 'element:3']
и сохранит в переменную newList
.
В случае, если в рамках итерации тег return
не был вызван, элемент списка пропускается.
Таким образом, используя трансформацию, можно отфильтровать список:
{% transform item in [1, 2, 3] as newList %}
{% if (item != 2) %}
{% return item %}
{% endif %}
{% endtransform %}
{{ newList }}
Предыдущий пример преобразует список [1, 2, 3]
в [1, 3]
, исключая из результата второй элемент согласно установленному условию.
Информация
Трансформации наследуют все особенности работы циклов for
, включая переменную loop
и доступ к родительскому контексту.
Внимание
Трансформации не могут использовать вложенные списки/карты, такие элементы будут исключены из результата трансформации. Другими словами, нельзя делать списки списков и списки карт.
Кроме этого, трансформации ничего не печатают в шаблон, все островки вывода внутри трансформаций игнорируются.
break/continue
#
Вы можете прерывать выполнение итераций циклов и трансформаций, используя теги break
и continue
.
break
прерывает текущую и все последующие итерации цикла:
{% for item in [1, 2, 3, 4] %}
start:{{item}}
{% if (item > 2) %}
{% break %}
{% endif %}
end:{{item}}
{% endfor %}
Предыдущий пример распечатает start:1 end:1 start:2 end:2 start:3
, поскольку третья и все последующие итерации прерываются условием item > 2
.
continue
прерывает только текущую итерацию цикла:
{% for item in [1, 2, 3] %}
start:{{item}}
{% if (item == 2) %}
{% continue %}
{% endif %}
end:{{item}}
{% endfor %}
Предыдущий пример распечатает start:1 end:1 start:2 start:3 end:3
. Обратите внимание на отсутствие части end:2
, так как вторая итерация прерывается выполнением условия item == 2
.
return
#
Команда return
прерывает генерацию шаблона и возвращает ошибку.
{% return 'Произошла какая-то ошибка' %}
Вместо строки можно передать заполненный Embed (но НЕ отправляя его функцией send
).
Данный тег также используется в трансформациях.
Прочее#
macro
#
Макросы — конструкции, позволяющие минимизировать дублирование однообразного кода шаблона.
Это достигается вынесением переиспользуемой части шаблона в именованную конструкцию macro/endmacro
, которая также предоставляет возможность передачи внутрь каких-либо входных данных:
{% macro macroName(firstArgument, secondArgument, ...) %}
... переиспользуемый шаблон ....
{% endmacro %}
Название макроса#
Названием макроса должен быть уникальный идентификатор. Макрос с конкретным названием может быть определён только один раз, попытка повторно определить макрос с уже существующим названием приведёт к ошибке исполнения шаблона.
Аргументы макроса#
Аргументы макроса — список идентификаторов, представляющие собой входные переменные, которые можно использовать внутри макроса. Список аргументов опционален, Вы можете создать макрос вообще без аргументов. Их передача так же опциональна.
Область видимости#
Шаблон макроса имеет доступ к ограниченному числу переменных:
- Переданные в макрос аргументы;
- Переменные, объявленные глобально на момент запуска макроса;
- Переменные, доступные в шаблоне по-умолчанию.
Обычные переменные, объявленные внутри макроса, доступны только в контексте выполнения этого макроса. Глобальные будут ожидаемо доступны во всем шаблоне.
Запуск макроса#
Объявленные макросы запускаются аналогично встроенным функциям. Их можно считать своего рода "пользовательскими функциями".
{% macro fullname(firstName, lastName) %}
{{ firstName ~ ' ' ~ lastName }}
{% endmacro %}
{{ fullname('Илон', 'Маск') }}
В данном примере мы создали простейший макрос для получения полного имени из двух входных переменных (имени и фамилии). Результатом вызова макроса является строка, получившаяся в результате обработки шаблона этого макроса с указанными аргументами.
Кроме этого, Вы можете использовать тэг return для случаев, когда макрос должен вернуть значение какой-либо конкретной переменной или выражения, например:
{% macro fullname(firstName, lastName) %}
Блаблабла
{% return firstName ~ ' ' ~ lastName %}
{% endmacro %}
{{ fullname('Илон', 'Маск') }}
Результат выполнения этого шаблона будет аналогичен предыдущему. Обратите внимание на "Блаблабла" в шаблоне макроса. В данном случае этот текст выведен не будет, поскольку макрос использует return для возврата конкретных данных.
Внимание
Макросы не могут запускать другие макросы.
filter
#
Конструкция фильтра — ещё одна возможность применять функции к указанному контенту. Она использует содержимое указанного тела блока как аргумент для указанной функции.
{% filter lower | capitalize -%}
HELLO WORLD
{%- endfilter %}
Предыдущий пример распечатает сообщение Hello world
. Как мы видим, результатом фильтра является выполнение двух функций над телом блока. Сперва фильтр применяет функцию lower
к содержимому HELLO WORLD
, генерируя hello world
, после этого применяет функцию capitalize
, генерируя результирующее Hello world
.
verbatim
#
Этот тег полезен для избежания вычисления любого синтаксиса шаблонного движка, то есть оно не будет вычислять содержимое этого блока и распечатает его как есть.
{% verbatim %}
{{ test }}
{% endverbatim %}
Предыдущий пример распечатает сообщение {{ test }}
.