Перейти к содержимому

Теги ​

Теги — набор различных встроенных конструкций и операций над шаблоном. Они объявляются с помощью островков кода и определяют поведение шаблона.

Рекомендация

Перед изучением тегов рекомендуется ознакомиться со статьями Типы данных и Конвертация типов.

Команды ​

Теги команд выполняют какую-либо операцию, но ничего не печатают в результат шаблона.

set ​

Команда set является операцией присваивания переменной в шаблоне. Она вычислит результат выражения и запишет его в переменную с указанным названием:

JuniperBot Template
{% set five = 2 + 3 %}

В примере выше результат вычисления 2 + 3 (5) будет записан в переменную five.

Команда set также поддерживает составные операторы присваивания, используя основные бинарные операторы для арифметических операций (+, -, *, **, /, //) и объединения строк (~):

JuniperBot Template
{% set value = 2 %}
{% set value += 3 %}

В примере выше результирующее значение переменной будет равно 5.

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

set как команда не генерирует контент, она просто объявляет переменную или перезаписывает существующую переменную с этим именем.

global ​

Переменные, объявленные командой set, имеют локальную область видимости и будут доступны только в шаблоне, в котором они были объявлены. Команда global позволяет объявить переменную глобально.

Это значит, что эта переменная будет доступна в последующих интерпретируемых шаблонах этого сообщения, в макросах и в действии, вызываемом через run. Например, переменная, определенная глобальной в шаблоне сообщения станет сразу доступна в шаблоне панели.

JuniperBot Template
{% global six = 3 + 3 %}

В примере выше результат вычисления 3 + 3 (6) будет записан в переменную six и доступен глобально.

Локальное переопределение

Переменная, объявленная командой set, имеет локальную область видимости, поэтому она может переопределить значение переменной, ранее объявленное командой global с таким же названием. Она не перезапишет значение глобальной переменной, а именно что переопределит его.

Сбросить переопределённое значение set и вернуть переменной её глобальное значение можно, указав этой переменной неопределённое значение, например, названием любой несуществующей переменной:

JuniperBot Template
{% global value = 'global_value' %}
{{ value }}
{# ^ распечатает "global_value" #}
{% set value = 'set_value' %}
{{ value }}
{# ^ распечатает "set_value" #}
{% set value = undefined %}
{# ^ "undefined" может быть название любой несуществующей переменной #}
{{ value }}
{# ^ распечатает "global_value" #}

do ​

Команда do вычисляет указанное выражение, не печатая ничего в шаблон.

JuniperBot Template
{% do channel.sendMessage('My message!') %}

Данная команда может быть полезна для тихого вызова каких-либо функций или методов у объектов.

require ​

Команда require является расширением тэга return и выглядит следующим образом:

JuniperBot Template
{% require выражение returning 'Произошла какая-то ошибка' %}

Эта команда вернет ошибку если результат вычисления выражения будет равен:

  • null;
  • undefined;
  • false;
  • пустая строка;
  • 0.

Вместо строки можно передать заполненный Embed (но НЕ отправляя его методом send).

Будучи расширением тэга return, данная команда имеет аналогичное поведение в трансформациях и макросах.

use ​

Команда use включает дополнительную функциональность шаблонного движка или меняет его поведение.

strict ​

Выполнение шаблона в строгом режиме. Это означает, что шаблонный движок будет возвращать ошибку компиляции в следующих случаях:

  • Попытка вывести неопределённую переменную;
  • Попытка обратиться к несуществующему свойству объекта;
  • Попытка вызвать несуществующую функцию, метод объекта или с некорректно переданными в неё аргументами.

Строгий режим включается следующим образом:

JuniperBot Template
{% use 'strict' %}

run ​

Команда run используется для запуска указанного Действия с передачей в него параметров (опционально). Эта операция полностью прервёт текущее выполняемое действие.

Внимание

Данный тег работает только в Действиях пользовательских команд для "маршрутизации" одного действия в другое.

Используйте UUID действия для его запуска:

JuniperBot Template
{% run 'aebf9ae8-c62a-4348-b153-a7c0a0173da1' %}

Информация

Вы можете получить этот UUID из самого действия в настройках команды (нажмите иконку "i").

Оба действия должны быть частью одной команды, т.е. действие команды А не может быть запущено из действия команды Б.

Для передачи параметров в запускаемое действие используйте следующий синтаксис:

JuniperBot Template
{% run 'aebf9ae8-c62a-4348-b153-a7c0a0173da1' with { 'param1': 123 } %}

Выражение после with на самом деле просто карта, поэтому можно указать там объявленную ранее переменную карты. Эти параметры будут доступны как часть переменной parameters в запускаемом действии:

JuniperBot Template
{{ parameters.param1 }}

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

Вы также можете использовать сам parameters в родительском действии для передачи данных в дочернее. Следующий пример сделает абсолютно то же самое, как и предыдущий, просто другим способом:

JuniperBot Template
{% do parameters.store('param1', 123) %}
{% run 'aebf9ae8-c62a-4348-b153-a7c0a0173da1' %}

Внимание

Действия могут запускать друг друга цепочкой до трёх раз. Квоты методов при этом остаются общие для всей цепочки.

Управляющие конструкции ​

Шаблонный движок JuniperBot реализует базовые управляющие конструкции: условия и циклы

Условия — if/elseif/else ​

Условие — самая простая управляющая конструкция. Здесь поддерживаются последовательные конструкции elseif, а также распространённую конструкцию else.

JuniperBot Template
{% if (выражение) %}
... Блок вычисляется если "выражение" вычислено как true ...
{% elseif (другоеВыражение) %}
... Блок вычисляется если "другоеВыражение" вычислено как true,
 а так же "выражение" вычислено как false ...
{% else %}
... Блок вычисляется если ни одно из 
указанных условий не было удовлетворено ...
{% endif %}

Обратите внимание, что вся конструкция if выведет содержимое только первого блока, выражение которого будет вычислено как true согласно правилам Конвертации типов.

С точки зрения области видимости переменных, внутреннее содержимое блока if разделяет контекст с родительским контекстом. Это означает, что условия могут влиять на переменные во внешней области видимости.

JuniperBot Template
{% set variable = "раз" %}
{% if (true) %}
    {% set variable = "два" %}
{% endif %}
{{ variable }}

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

JuniperBot Template
{% if (1 != 2) %}
    {% return 'Один не равен двум. Внезапно!' %}
{% endif %}
А вот этот текст шаблон не выведет из-за ошибки.

Пример выше демонстрирует, как можно с помощью условия вернуть ошибку.

Циклы — for ​

Поддерживаются циклы над списками или картами.

JuniperBot Template
{# Пример цикла над списком #}
{% for item in list %}
... Контент с использованием переменной item ...
{% endfor %}

{# Пример цикла над картой #}
{% for key, value in map %}
... Контент с использованием переменных key и value карты ...
{% endfor %}

Область видимости переменных-итераторов (item, key, value в примерах выше) ограничена лишь блоком цикла, даже если их переопределять с помощью команды set.

Переменная loop ​

Циклы for объявляют дополнительную переменную с идентификатором loop. Она предоставляет доступ к полезным свойствам внутри цикла:

СвойствоОписание
lengthРазмер списка или карты
indexНомер текущей итерации, начинающийся с 1
index0Номер текущей итерации, начинающийся с 0
revindexКоличество оставшихся итераций до достижения конца списка или карты, заканчивается на 1
revindex0Количество оставшихся итераций до достижения конца списка или карты, заканчивается на 0
firstСвойство, равное true для самой первой итерации
lastСвойство, равное true для самой последней итерации
parentПолучение доступа к родительскому контексту
JuniperBot Template
{% for item in [1, 2, 3] %}
    {% if (loop.first) %}
        Начало
    {% endif %}
{% endfor %}

Предыдущий пример распечатает слово Начало только один раз во время первой итерации.

Переменная loop привязана к контексту цикла for, это значит, что область видимости этой переменной ограничена лишь содержимым блока цикла. Если вне цикла объявлена переменная с названием loop, она не будет перезаписана, но доступ к ней можно будет получить только через родительский контекст, например:

JuniperBot Template
{% 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 самого цикла. Эта переменная далее будет доступна уже вне цикла.

Ограничения

  1. Максимально допустимая вложенность циклов — 2;
  2. Максимальное количество итераций всех циклов в процессе выполнения одного шаблона — 3000.

Трансформации — transform ​

Трансформация - разновидность цикла for, используемая для преобразования одного списка в другой. Каждая итерация такого цикла ожидает вызов тега return с указанием нового значения для соответствующего элемента списка:

JuniperBot Template
{% transform item in [1, 2, 3] as newList %}
    {% return 'element:' ~ item %}
{% endtransform %}
{{ newList }}

Предыдущий пример преобразует список [1, 2, 3] в ['element:1', 'element:2', 'element:3'] и сохранит в переменную newList.

В случае, если в рамках итерации тег return не был вызван, элемент списка пропускается. Таким образом, используя трансформацию, можно отфильтровать список:

JuniperBot Template
{% 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 прерывает текущую и все последующие итерации цикла:

JuniperBot Template
{% 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 прерывает только текущую итерацию цикла:

JuniperBot Template
{% 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 прерывает генерацию шаблона и возвращает ошибку. Он также используется в трансформациях и макросах.

JuniperBot Template
{% return 'Произошла какая-то ошибка' %}

Вместо строки можно передать заполненный Embed (но НЕ отправляя его функцией send).

Вы также можете передать null, это предотвратит отправку любого результата шаблона, включая любые ошибки:

JuniperBot Template
{% return null %}

Прочее ​

macro ​

Макросы — конструкции, позволяющие минимизировать дублирование однообразного кода шаблона.

Это достигается вынесением переиспользуемой части шаблона в именованную конструкцию macro/endmacro, которая также предоставляет возможность передачи внутрь каких-либо входных данных:

JuniperBot Template
{% macro macroName(firstArgument, secondArgument, ...) %}
  ... переиспользуемый шаблон ....
{% endmacro %}

Название макроса ​

Названием макроса должен быть уникальный идентификатор. Макрос с конкретным названием может быть определён только один раз, попытка повторно определить макрос с уже существующим названием приведёт к ошибке исполнения шаблона.

Аргументы макроса ​

Аргументы макроса — список идентификаторов, представляющие собой входные переменные, которые можно использовать внутри макроса. Список аргументов опционален, Вы можете создать макрос вообще без аргументов. Их передача так же опциональна.

Область видимости ​

Шаблон макроса имеет доступ к ограниченному числу переменных:

  • Переданные в макрос аргументы;
  • Переменные, объявленные глобально на момент запуска макроса;
  • Переменные, доступные в шаблоне по-умолчанию.

Обычные переменные, объявленные внутри макроса, доступны только в контексте выполнения этого макроса. Глобальные будут ожидаемо доступны во всем шаблоне.

Запуск макроса ​

Объявленные макросы запускаются аналогично встроенным функциям. Их можно считать своего рода "пользовательскими функциями".

JuniperBot Template
{% macro fullname(firstName, lastName) %}
  {{ firstName ~ ' ' ~ lastName }}
{% endmacro %}

{{ fullname('Илон', 'Маск') }}

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

Кроме этого, Вы можете использовать тэг return для случаев, когда макрос должен вернуть значение какой-либо конкретной переменной или выражения, например:

JuniperBot Template
{% macro fullname(firstName, lastName) %}
  Блаблабла
  {% return firstName ~ ' ' ~ lastName %}
{% endmacro %}

{{ fullname('Илон', 'Маск') }}

Результат выполнения этого шаблона будет аналогичен предыдущему. Обратите внимание на "Блаблабла" в шаблоне макроса. В данном случае этот текст выведен не будет, поскольку макрос использует return для возврата конкретных данных.

Внимание

Макросы не могут запускать другие макросы.

include ​

Данный тег используется для вставки глобального шаблона в текущий шаблон. Для более подробной информации посетите статью Глобальные шаблоны.

JuniperBot Template
{% include 'my_template' %}

В данном примере мы вставили глобальный шаблон с названием my_template.

Область видимости ​

По-умолчанию глобальный шаблон выполняется полностью в контексте основного шаблона. Простыми словами, он выполняется буквально если бы вместо тэга include было вставлено содержимое этого шаблона.

Все объявленные в основном шаблоне переменные будут доступны внутри глобального шаблона, а все переменные, объявленные внутри глобального шаблона, станут доступны в основном шаблоне после выполнения тэга include.

Однако, данное поведение можно изменить с помощью дополнительного ключа scoped:

JuniperBot Template
{% include 'my_template' scoped %}

В данном случае глобальный шаблон будет выполнен в собственном контексте. Он не будет иметь доступ к переменным, объявленным в основном шаблоне, а переменные, созданные в процессе выполнения глобального шаблона, не будут доступны в основном шаблоне.

"Внимание"

Глобальные переменные и макросы являются исключением.

Даже в режиме scoped они будут доступны в глобальных шаблонах, и их объявление сделает их доступными в основном шаблоне.

В случае, когда в режиме scoped всё же необходимо передать какие-то данные внутрь глобального шаблона, можно использовать следующую конструкцию:

JuniperBot Template
{% include 'my_template' scoped with { 'param1': 123 } %}

Выражение после with на самом деле просто карта, поэтому можно указать там объявленную ранее переменную карты. Указанные данные будут доступны как обычные переменные внутри глобального шаблона.

В примере выше переменная param1 будет иметь значение 123.

filter ​

Конструкция фильтра — ещё одна возможность применять функции к указанному контенту. Она использует содержимое указанного тела блока как аргумент для указанной функции.

JuniperBot Template
{% filter lower | capitalize -%}
HELLO WORLD
{%- endfilter %}

Предыдущий пример распечатает сообщение Hello world. Как мы видим, результатом фильтра является выполнение двух функций над телом блока. Сперва фильтр применяет функцию lower к содержимому HELLO WORLD, генерируя hello world, после этого применяет функцию capitalize, генерируя результирующее Hello world.

verbatim ​

Этот тег полезен для избежания вычисления любого синтаксиса шаблонного движка, то есть оно не будет вычислять содержимое этого блока и распечатает его как есть.

JuniperBot Template
{% verbatim %}
{{ test }}
{% endverbatim %}

Предыдущий пример распечатает сообщение {{ test }}.

Все права зафырканы.