Перейти к содержанию

Теги

Описание всех доступных тегов шаблонного движка 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 }}.