+7 (999) 881-15-11

«Арете — сервер мессенджеров, Max edition»

Руководство по шаблонизатору

Шаблонизатор собирает текст сообщения из справочника «АСМ — Шаблоны»: подставляет переменные, отрезает блоки по условиям, обходит коллекции и вырезает именованные области. Текст шаблона правят в режиме 1С:Предприятия, без конфигуратора. История версий остаётся в элементе справочника.

Справочник шаблонов

Содержимое живёт в справочнике АСМ — Шаблоны, а не в коде модуля. Код элемента — идентификатор, который вы передаёте в ВывестиПоШаблону. Пользователь с правами на подсистему может править текст в предприятии: поменяли формулировку — бот в следующем сообщении уже говорит по-новому.

История хранится в табличной части «Версии шаблона». У версии есть содержание, номер, дата, комментарий и признак «Актуальная». Актуальная может быть только одна: при записи остальные признаки снимаются, а реквизиты шапки копируются из выбранной строки. Пустая табличная часть не запишется. Чтобы откатиться после неудачной правки, отметьте предыдущую строку как актуальную и запишите элемент.

При записи шаблона подсистема вызывает ОбновитьПовторноИспользуемыеЗначения. Разобранный текст кэшируется в АСМ_НастройкиПовтИсп.ТокенизироватьШаблон — после записи кэш сбрасывается сам, отдельно сеанс перезапускать не нужно.

Заготовки для нового бота кладут в СведенияОбОбработчике. ИнициализацияОбработчика вызывает АСМ_Служебный.СоздатьШаблоныОбработчика: элемент создаётся по коду-идентификатору (или берётся существующий), сверху табличной части добавляется версия «По умолчанию» и помечается актуальной. Старые версии не удаляются — откат по-прежнему через признак «Актуальная». Повторная инициализация снова положит поставку сверху.

Заготовка шаблона в сведениях обработчика
Идентификатор станет кодом элемента справочника. Текст обычно берут из макета обработки.
Шаблон = Сведения.ШаблоныПоУмолчанию.Добавить();
Шаблон.Идентификатор = "УведомлениеОЗаказе";
Шаблон.Содержимое = ПолучитьМакет("УведомлениеОЗаказе").ПолучитьТекст();
Шаблон.Комментарий = "Сообщение о новом заказе";
Создание шаблонов при подключении обработчика
АСМ_Служебный.СоздатьШаблоныОбработчика(СведенияОбОбработчике());

Вызов из обработчика

Два метода общего модуля АСМ_Шаблонизатор. Оба возвращают строку. Первый параметр — код шаблона, второй — имя области (или Неопределено), третий — структура параметров.

ВывестиПоШаблону

Берёт актуальную версию шаблона, подставляет параметры, возвращает готовый текст. Если элемента с таким кодом нет, вернётся пустая строка.

Содержимое шаблона
Поступил заказ от #клиент на сумму #сумма
Формирование ответа
Второй аргумент Неопределено — весь шаблон (для шаблона без областей) либо все области подряд.
ПараметрыШаблона = Новый Структура;
ПараметрыШаблона.Вставить("клиент", "ООО Ромашка");
ПараметрыШаблона.Вставить("сумма", 15000);

Текст = АСМ_Шаблонизатор.ВывестиПоШаблону("УведомлениеОЗаказе", Неопределено, ПараметрыШаблона);
Параметры = Новый Структура("text", Текст);
АСМ_М.ОтправитьСообщение(Бот, Параметры, Вход);

Если в шаблоне нет @область, второй аргумент не участвует в отборе — достаточно Неопределено. Если области есть, пустая строка "" не совпадёт ни с одним именем и метод вернёт пусто. Для «всех областей подряд» передавайте Неопределено, для одного фрагмента — имя области.

Весь шаблон
Текст = АСМ_Шаблонизатор.ВывестиПоШаблону("УведомлениеОЗаказе", Неопределено, ПараметрыШаблона);
Одна именованная область
Текст = АСМ_Шаблонизатор.ВывестиПоШаблону("ШаблонОбласти", "краткая", ПараметрыШаблона);

ДобавитьПоШаблону

То же вычисление, но результат дописывается к уже набранному тексту: Текст + ВывестиПоШаблону(…). Удобно собирать сообщение из нескольких областей одного макета или из разных шаблонов.

Последовательная сборка
Параметры = ПараметрыШаблонаСборка();
Текст = "";
Текст = АСМ_Шаблонизатор.ДобавитьПоШаблону(Текст, "ШаблонСборка", "заголовок", Параметры);
Текст = АСМ_Шаблонизатор.ДобавитьПоШаблону(Текст, "ШаблонСборка", "список", Параметры);

# и @ здесь — не роутинг. В роутинге #имя — переменная роутера, @имя — именованное условие. В шаблоне #имя — параметр вывода, @если / @для / @область — директивы языка. Это разные словари.

Язык шаблона

Шаблон — обычный текст плюс конструкции, которые начинаются с # и @. Регистр директив и имён не важен. Имя — как ключ структуры: буква или подчёркивание, дальше буквы, цифры и подчёркивания (латиница и кириллица).

Конструкция Назначение
#имя Подстановка значения из параметров
#объект.поле Поле структуры, соответствия или колонка строки таблицы — один уровень
@если #имя@иначе@конецесли Ветвление; @иначе можно опустить
@для каждого элемент из #коллекция цикл@конеццикла Обход массива структур или таблицы значений
@область имя@конецобласти Именованный фрагмент для выборочного вывода

Вложенные циклы запрещены. Вложенные области запрещены. Условие внутри цикла и цикл внутри условия — можно. Условия можно вкладывать друг в друга.

Если переменной нет в параметрах, на её месте останется исходный текст (#имя как написали). То же с незакрытым или «битым» @если / @для: кусок не вычисляется, а копируется в результат как есть. Так проще заметить опечатку в чате, чем получить пустое сообщение.

Переменные

Параметры — структура. Ключи сравниваются без учёта регистра: Клиент и клиент — одно имя. Значение выводится через Строка(…).

#объект.поле сначала ищет объект среди локальных переменных цикла, затем в параметрах. Поле читается из структуры или соответствия (тоже без учёта регистра) либо как Основание[Поле] — так работают колонки таблицы значений. Цепочки вида #заказ.клиент.имя нет: одна точка.

Подстановка переменных
Здравствуйте, #клиент!
Сумма заказа: #сумма
Поле структуры в условии и в тексте
@если #пользователь.имя
Клиент: #пользователь.имя, роль — #пользователь.роль
@конецесли
Параметры, которые передают в ВывестиПоШаблону:
Пользователь = Новый Структура;
Пользователь.Вставить("имя", Строка(Вход.Пользователь));
Пользователь.Вставить("роль", "пользователь Max");

Параметры = Новый Структура;
Параметры.Вставить("пользователь", Пользователь);

Условия

После @если — одна переменная: #имя или #объект.поле. Сравнений вроде #сумма > 0 в языке шаблона нет: подготовьте булево, число или строку в параметрах.

Что считается истиной:

Другой тип вызовет исключение. Если переменной нет, в результат попадёт исходный текст всего блока @если@конецесли, без выбора ветки.

Условие: есть имя или нет
@если #имя
Здравствуйте, #имя!
@иначе
Здравствуйте!
@конецесли
Условие: корзина пуста или нет
В @если одна переменная: для числа «не ноль», для строки — заполнена.
@если #товаровВКорзине
Товаров в корзине: #товаровВКорзине
@иначе
Корзина пуста
@конецесли

Циклы

Коллекция — массив структур или таблица значений. Массив простых значений (строк, чисел) не подходит: движок вернёт исходный текст цикла.

Имя элемента после каждого можно писать с # или без. Внутри тела элемент доступен как #имя и #имя.поле. После цикла это имя из локальных переменных убирается.

Параметры для обхода
Методы = Новый Массив;

Метод = Новый Структура("код, описание", "GET /me", "данные бота");
Методы.Добавить(Метод);
Метод = Новый Структура("код, описание", "POST /messages", "отправка сообщения");
Методы.Добавить(Метод);

Параметры = Новый Структура;
Параметры.Вставить("методы", Методы);
Параметры.Вставить("количество", Методы.Количество());
Обход коллекции
Состав заказа:

@для каждого позиция из #позиции цикл
• #позиция.номенклатура — #позиция.количество шт. × #позиция.цена
@конеццикла

Итого позиций: #количество
Обход коллекции и условие по полю элемента
@для каждого товар из #товары цикл
#товар.наименование — #товар.цена
@если #товар.скидка
скидка: #товар.скидка
@конецесли
@конеццикла

Области

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

Имя области во втором аргументе ВывестиПоШаблону сравнивается без учёта регистра. Неопределено — все области шаблона по порядку. Конкретное имя — только этот фрагмент.

Именованные области
Вызов: ВывестиПоШаблону(Шаблон, "краткая", Параметры) — только выбранный фрагмент.
@область краткая
Статус заявки #номер: #статус
@конецобласти

@область подробная
Заявка #номер
Клиент: #клиент.имя
Статус: #статус
@конецобласти

Сборка из нескольких фрагментов

Один макет может содержать несколько областей («заголовок», «список», «подвал»). В коде выбираете, какие куски сложить и в каком порядке — через ДобавитьПоШаблону с одним и тем же идентификатором и разными именами областей. Параметры общие.

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

Частые ошибки