---
url: /templates/advanced/tags.md
description: >-
Все теги шаблонного движка — set, global, do, if, for, break, continue,
transform, macro, include, filter, verbatim, require, return, use, run.
---
# Теги
Теги пишутся в островках {% %} и управляют выполнением шаблона: запоминают значения, проверяют условия, повторяют текст, объявляют свои функции и подключают общие шаблоны.
| Тег | Коротко |
|---|---|
| [`set`](#set) | Запомнить значение в переменной |
| [`global`](#global) | Переменная, видимая в других полях сообщения и в следующих действиях |
| [`do`](#do) | Вычислить выражение, ничего не выводя |
| [`if`](#if) | Условие |
| [`for`](#for) | Цикл |
| [`break`, `continue`](#break) | Выход из цикла и переход к следующему шагу |
| [`transform`](#transform) | Превратить список в новый список |
| [`macro`](#macro) | Своя функция |
| [`include`](#include) | Подключить общий шаблон |
| [`filter`](#filter) | Применить функции к куску текста |
| [`verbatim`](#verbatim) | Вывести текст без обработки |
| [`require`](#require) | Остановиться с сообщением, если условие не выполнено |
| [`return`](#return) | Остановиться или вернуть значение из макроса |
| [`use`](#use) | Включить строгий режим |
| [`run`](#run) | Запустить другое действие команды |
## set { #set }
Создает или меняет локальную переменную.
```template
{% set name = member.firstName %}
{% set total = 10 %}
{% set total += 5 %} {# 15 #}
```
Составные операторы: `+=`, `-=`, `*=`, `**=`, `/=`, `//=`, `~=` (дописать строку).
Переменная, созданная внутри `if` или `for`, видна и после него: `set` пишет в переменные шаблона (или макроса).
## global { #global }
Глобальная переменная видна:
* в следующих полях этого же сообщения;
* в [макросах](#macro);
* в действии, запущенном через [`run`](#run).
```template
{% global discount = 20 %}
```
Если объявить `set` с тем же именем, локальная переменная перекроет глобальную. `{% set discount = undefined %}` снимет перекрытие.
## do { #do }
Вычисляет выражение и ничего не выводит. Нужен для функций с «побочным эффектом»: кнопок, реакций, записи данных.
```template
{% do url_button('Правила', 'https://telegra.ph/pravila-chata') %}
{% do reaction('👍') %}
{% do member.getAttribute('visits').increment(1) %}
```
## if { #if }
```template
{% if member.rank.level >= 50 %}
Легенда
{% elseif member.rank.level >= 10 %}
Ветеран
{% else %}
Новичок
{% endif %}
```
Условия проверяются сверху вниз, выполняется первая подходящая ветка. `elseif` и `else` необязательны. Как значения превращаются в «да» и «нет» — см. [Истинность](./types#truthy).
## for { #for }
Повторяет кусок шаблона для каждого элемента списка, диапазона, карты или [страницы индекса](/reference/chat-index#page).
```template
{% for mode in ['Броулбол', 'Нокаут', 'Ограбление'] %}
- {{ mode }}
{% endfor %}
```
Для карт можно получать ключ и значение:
```template
{% for key, value in { vip: 500, premium: 1000 } %}
{{ key }} — {{ value }} 🪙
{% endfor %}
```
Ветка `else` выполняется, если список пуст:
```template
{% for m in winners %}
- {{ m }}
{% else %}
Победителей пока нет.
{% endfor %}
```
### Переменная loop { #loop }
Внутри цикла доступна переменная `loop`:
| Свойство | Что в нем |
|---|---|
| `loop.index` | Номер шага с 1 |
| `loop.index0` | Номер шага с 0 |
| `loop.revindex` | Сколько шагов осталось, считая текущий (до 1) |
| `loop.revindex0` | То же, до 0 |
| `loop.first` | `true` на первом шаге |
| `loop.last` | `true` на последнем шаге |
| `loop.length` | Сколько всего элементов |
| `loop.parent` | `loop` внешнего цикла во вложенном цикле |
```template
{% for m in top %}{{ loop.index }}. {{ m.name }}{{ loop.last ? '' : ', ' }}{% endfor %}
```
::: info Лимиты циклов
Все циклы одного выполнения вместе могут сделать не больше 5 000 шагов, а вложить можно не больше трех циклов друг в друга. См. [Квоты](./limits).
:::
## break и continue { #break }
`break` сразу выходит из цикла, `continue` пропускает остаток текущего шага.
```template
{% for m in club.members %}
{% if m.trophies < 10000 %}{% continue %}{% endif %}
{% if loop.index > 10 %}{% break %}{% endif %}
{{ m.name }}
{% endfor %}
```
## transform { #transform }
Создает из списка новый список. Для каждого элемента выполняется тело, и то, что вернул `return`, попадает в новый список. Элементы без `return` пропускаются. Сам тег ничего не выводит.
```template
{% transform m in club.members as names %}
{% if m.trophies >= 30000 %}{% return m.name %}{% endif %}
{% endtransform %}
Сильнейшие: {{ names | join(', ') }}
```
Вложенные списки и карты в результате отбрасываются. Внутри работают `break` и `continue`.
## macro { #macro }
Макрос — своя функция: кусок шаблона с параметрами, который можно вызывать много раз.
```template
{% macro medal(place) %}
{%- if place == 1 %}🥇{% elseif place == 2 %}🥈{% elseif place == 3 %}🥉{% else %}{{ place }}.{% endif -%}
{% endmacro %}
{% for m in top %}
{{ medal(loop.index) }} {{ m.name }}
{% endfor %}
```
* Результат макроса — текст его тела. Если в макросе есть `{% return значение %}`, результатом будет это значение.
* Макрос видит свои параметры, глобальные переменные и данные контекста (`member`, `chat`…), но не локальные переменные того, кто его вызвал.
* Макросы можно вызывать через pipe: `{{ loop.index | medal }}`.
* Макрос может вызывать другие макросы — до 16 уровней вложенности.
* Два макроса с одинаковым именем — ошибка `duplicate_macro`.
Макросы, которые нужны в нескольких командах, удобно вынести в [общий шаблон](../shared).
## include { #include }
Вставляет [общий шаблон](../shared) по имени.
```template
{% include 'header' %}
{% include 'profile-card' scoped %}
{% include 'profile-card' scoped with { user: arguments.targetMember } %}
```
| Вариант | Как выполняется |
|---|---|
| `include 'имя'` | Как будто текст общего шаблона вставили на это место: он видит и меняет ваши переменные |
| `include 'имя' scoped` | Изолированно: свои переменные не видны и не меняются. Глобальные переменные и данные контекста видны |
| `… scoped with { k: v }` | Изолированно, с переданными переменными |
Макросы, объявленные во вставленном шаблоне, становятся доступны после `include`. За одно выполнение можно вставить до 5 общих шаблонов, каждый — один раз.
## filter { #filter }
Применяет одну или несколько функций ко всему тексту внутри:
```template
{% filter lower | capitalize %}
ПРАВИЛА ЧАТА ОБНОВЛЕНЫ
{% endfilter %}
```
Результат: «Правила чата обновлены».
## verbatim { #verbatim }
Выводит содержимое как есть, не обрабатывая островки:
```template
{% verbatim %}Пример: {{ member.name }}{% endverbatim %}
```
## require { #require }
Останавливает шаблон, если условие ложно, и отвечает указанным текстом.
```template
{% require arguments.targetMember returning 'Укажите участника!' %}
{% require arguments.get(2) is number returning 'Сумма должна быть числом' %}
```
Ложным считаются `null`, `Undefined`, `false`, пустая строка и `0`. После `returning` можно указать строку или несобранный построитель сообщения ([MessageBuilder](/reference/message-builder)).
## return { #return }
Ведет себя по-разному в зависимости от места:
| Где | Что делает |
|---|---|
| В основном шаблоне | Останавливает шаблон. `{% return 'текст' %}` — ответить этим текстом как ошибкой. `{% return null %}` — ничего не отправлять |
| В [макросе](#macro) | Возвращает значение из макроса |
| В [transform](#transform) | Добавляет элемент в новый список |
## use { #use }
```template
{% use 'strict' %}
```
Включает [строгий режим](./types#strict): необъявленные переменные, неизвестные свойства и ошибки типов становятся ошибками.
## run { #run }
Только в действиях [пользовательских команд](/commands/). Завершает текущее действие и запускает другое действие той же команды.
```template
{% run 'ae04dfed-e19c-49d3-84fc-b05cec59976e' %}
{% run 'ae04dfed-e19c-49d3-84fc-b05cec59976e' with { page: 0 } %}
{% run 'self' %}
```
Не больше 3 переходов в цепочке, квоты общие. Подробнее — [Цепочки действий](/commands/run).