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

Теги

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

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

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

Команды

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

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 }}.

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