Вызываются через символ пайпа |. Параметры передаются
через двоеточие :. Модификаторы можно выстраивать в
цепочку: {VAR|mod1|mod2:param}.
⚠️ Регистр в параметрах-ссылках на переменные: Если
параметр модификатора — это имя переменной или ключ поля, а не статичный
текст (как в calc, print,
array_item), парсер ищет его строго в том регистре,
в котором он записан — автоматического приведения к верхнему
регистру не происходит. Все ключи данных в шаблонизаторе (включая
вложенные массивы, переданные через TplAssign, и глобальный
массив) хранятся в UPPERCASE, поэтому и такие параметры нужно писать
заглавными буквами: {ROW|calc:PRICE*2}, а не
{ROW|calc:price*2} — иначе имя не будет найдено.
{BRAND|def:Без бренда} — Значение по
умолчанию.{DESC|short:150} — Обрезка. Оставляет
150 символов (по умолчанию 100) и добавляет .... Второй
параметр — свой суффикс вместо ...:
{DESC|short:150,читать далее}.{TEXT|html} — Безопасный вывод HTML-сущностей
(htmlspecialchars).{TEXT|slash} — Безопасный вывод
(addslashes).{TEXT|js} — Безопасная вставка в JS.
Оборачивает значение как JSON-строку (json_encode) и
дополнительно экранирует <, >,
&, ', ", чтобы значение
нельзя было использовать для выхода из строки или закрытия тега
</script>. Используйте для вставки PHP-значения прямо
в инлайновый <script>, например:
var name = {NAME|js};.{CONTENT|plain} — Мощная очистка.
Удаляет <script> и <style>,
вырезает HTML-теги, декодирует ,
© и схлопывает лишние пробелы. Идеально для
SEO-тегов.{BADGE|tag:span,badge,color: red} — Оборачивает
значение в HTML-тег. Параметры: тег,класс,style
(все, кроме тега, необязательны). {BADGE|tag} без
параметров обернёт в <span>. Если значение пустое —
тег не выводится вовсе (пустая строка). Если на входе массив (например,
список тегов товара) — обернёт каждый элемент отдельно
и склеит переносом строки: {TAGS|tag:span,tag-badge}.
Экранирование _cm_/_sp_ и т.п. работает и
здесь — см. таблицу ниже.Порядок важен: tag не экранирует
содержимое значения — если оно пришло от пользователя (не доверенный
HTML), сначала примените |html, и только потом
|tag:
{USER_COMMENT|html|tag:span,comment}.
{TEXT|print:VAR1,VAR2} — Гибкое форматирование
строк. Использует стандартный PHP sprintf для
подстановки значений в строку-шаблон.VAR1 не найдено в данных модуля (в
том числе если оно написано не в верхнем регистре), оно передается в
функцию как обычный текст.{ID|int} — Приведение к целому числу.
{ORDER_ID|pad:6,0} — Дополнение до
длины. Параметры: длина,символ (символ —
необязательно, по умолчанию 0).
{ORDER_ID|pad:6,0} для 42 даст
000042 (дополнение слева). Чтобы дополнить
справа, укажите длину с минусом:
{SKU|pad:-8, } дополнит пробелами справа до 8
символов.
{PRICE|num:2,., } — Форматирование.
Параметры: знаки, разделитель_дроби, разделитель_тысяч. По
умолчанию: 2, ,, '. Вывод:
1'250,50.
{QTY|nums:2} — Умное
форматирование. Отбрасывает нули, если число целое
(5.00 -> 5, но 5.50 ->
5,50).
{ROW|calc:PRICE-(OUT_PRICE/100)|num:0} —
Калькулятор. Безопасно вычисляет формулу, подставляя
ключи из массива {ROW}. {QTY|calc:VALUE*2} —
математика для одиночной переменной, используйте слово
VALUE внутри формулы. Имена переменных/полей в формуле —
строго UPPERCASE (см. правило выше); всё, что не распознано как имя
переменной или число, посчитается как 0.
Если применить calc не к одиночной записи, а к
списку записей (например, к галерее или списку
товаров), формула посчитается для каждой записи отдельно, и результатом
будет список чисел — точно так же, как одно значение, но во
множественном числе. Это удобно, когда нужно посчитать что-то для
каждого элемента списка без явного цикла {#...}:
{GOODS_LIST|calc:PRICE*0.9|num:2|join:, }Результат — строка вида 89.10, 45.00, 120.50 (по одному
числу на каждый товар в GOODS_LIST). Поскольку
calc возвращает массив, для вывода вне цикла его нужно
свести к строке — например, через |join, |json
или передать в цикл {#GOODS_LIST}...{GOODS_LIST#}, где
{ROW|calc:...} посчитает то же самое для текущего
элемента.
Подходит для простых разовых вычислений прямо в вёрстке (проценты
скидки, разница цен и т.п.); если формула становится длинной или
используется в нескольких местах — лучше посчитать значение в PHP и
передать готовым через TplAssign, по тем же причинам, что и
с составными условиями выше: так проще увидеть, что именно считается, и
переиспользовать расчёт.
{TIME|date:Y-m-d} — Умная дата.
Автоматически понимает как UNIX timestamp, так и строковые даты
(пропуская их через strtotime ISO 8601). Формат по
умолчанию: Y-m-d H:i.Эти модификаторы автоматически адаптируют форматы вывода под текущий
язык страницы (MELBIS()->LanguageSet('en')), используя
библиотеку ICU. Идеально для проектов с en,
ru, ua и т.д.
{PRICE|inum:2} — Форматирует число по правилам языка.
(В ru выведет 1 250,50, в en
выведет 1,250.50). Разделители указывать не нужно, только
количество знаков (по умолчанию 2).{QTY|inums:2} — То же самое, но отбрасывает дробную
часть для целых чисел (5.00 -> 5).{TIME|idate} — Умная локализованная дата. Без
параметров выводит стандартный для языка формат (ru: 9 апр. 2026 г.,
14:00, en: Apr 9, 2026, 2:00 PM).{TIME|idate:dd MMMM yyyy} — Пользовательский формат
даты. Важно: используется стандарт ICU, а не стандарт
PHP. Регистр имеет значение (например, месяц — это M, а
минуты — m).{ROW|join:, } — Склеивает плоский массив в
строку.
{ROW|json} / {ROW|js} — Конвертирует
массив в JSON. js использует HEX-экранирование тегов и
кавычек для безопасной вставки как массвов так и текстовых строк в
JavaSciprt.
Внутри инлайнового <script> используйте
js, а не json. Разница ровно в
экранировании: json оставляет <,
>, &, кавычки как есть, поэтому строка
из БД, содержащая </script>, разорвёт тег ещё до
того, как браузер дойдёт до JavaScript. js отдаёт их как
< и такой возможности не оставляет. Для вставки JSON в
атрибут или в тело страницы json подходит.
Числа приводятся к числам. Оба модификатора проходят
по массиву и превращают строковые значения, похожие на число, в
настоящие числа JSON: "1250.50" → 1250.5. Это
нужно потому, что из БД всё приезжает строками, а внешние потребители
(GTM, аналитика, API) ждут именно числовые типы. Правило приведения — то
же, что у is_numeric().
Ключи, которые обязаны остаться строкой, перечисляются параметром через запятую — заглавными буквами, как и везде в модификаторах:
{ECOMM|js:ITEM_ID,SKU}Это нужно для значений, которые выглядят как число, но числом не
являются: артикул 007 (иначе станет 7), код
1e5 (станет 100000), номер заказа с ведущими
нулями. Ключ ищется на любой глубине вложенности; если он указывает на
подмассив — нетронутым остаётся всё поддерево целиком.
{CSV|split:;,0} — Разбивает строку по
разделителю и берёт элемент по индексу. Параметры:
разделитель,индекс (индекс — с нуля).
{CSV|split:;,0} для строки
"Nikon;Aculon;10x42" вернёт "Nikon". Если
индекс не указан — {CSV|split:;} — возвращает весь
массив результатов, который можно дальше передать в
|join или вывести циклом
{#CSV}...{CSV#}.
{ROW|array_item:ADDRESS,CITY} — Достаёт
значение по ключу (или пути ключей через запятую) из уже готового
массива, например {ROW}. Пройдёт по вложенным
ключам ['ADDRESS']['CITY'] — путь, как и везде в
модификаторах, указывается в UPPERCASE, поскольку ключи массивов,
попавших в шаблон через TplAssign, всегда хранятся в
верхнем регистре. Если путь не ведёт к существующему ключу — вернёт
пустую строку. Без параметров — вернёт исходный массив без
изменений.
{JSON_FIELD|json_item:address,city} — То же самое,
что array_item, но входное значение — строка в
формате JSON, а не готовый PHP-массив: сначала декодирует JSON,
затем идёт по указанному пути ключей. Регистр здесь — исключение
из общего правила: ключи JSON не проходят через шаблонизатор и
не приводятся к верхнему регистру, поэтому путь нужно писать в том
регистре, в котором реально записаны ключи в самой JSON-строке (обычно —
как их сериализовал PHP/БД, то есть чаще в нижнем регистре, как в
примере выше). Если строка не является валидным JSON или путь не найден
— вернёт пустую строку.
Если путь у array_item/json_item указывает
не на конечное скалярное значение, а на вложенный массив/объект —
результатом будет массив; скомбинируйте с |join, если нужна
строка.
{UPLOAD_TIME|path} — Генерирует путь к директории
хранения файла на основе даты загрузки. Возвращает строку со слешем на
конце. В шаблоне используется вместе с именем файла:
<img src="{UPLOAD_TIME|path}{FILE_NAME}">.
{TEXT|text} — Добавляет базовый путь сайта к
относительным ссылкам src= и href= (использует
MELBIS_ROOT). Применяется к готовой HTML-разметке из базы:
описанию товара, тексту статьи, условиям доставки — то есть к
содержимому, где ссылки на файлы расставлял менеджер в
редакторе.
{TEXT|text:webp} — То же самое плюс перевод
картинок внутри текста в WebP. Режим находит в разметке все
src= и href=, ведущие на .jpg,
.jpeg и .png из каталога загруженных файлов, и
подменяет их на WebP-версии — конвертируя недостающие на лету и
складывая в кеш, как это делает модификатор |webp для
отдельной картинки.
Параметры совпадают с первыми двумя у |webp и передаются
в скобках: {TEXT|text:webp(80,1500)} — качество 80, бюджет
времени 1500 мс на страницу. Без скобок действуют значения по умолчанию:
качество 85, таймаут 1000.
<div class="description">{DESCRIPTION|text:webp}</div>Разница с |webp в области применения: |webp
работает с одной картинкой, путь к которой известен модулю, а
text:webp — с произвольным HTML, где картинок может быть
сколько угодно и модуль о них ничего не знает. Общий для страницы бюджет
времени защищает от того, что описание с двумя десятками ещё не
сконвертированных фотографий затормозит выдачу: как только бюджет
исчерпан, оставшиеся картинки отдаются в оригинале, а сконвертируются
при следующих открытиях страницы.
{ROW|webp:качество,таймаут_мс,поле_даты,поле_файла}
— Конвертация картинки в WebP на лету, с кэшированием.
Проверяет, есть ли уже готовая WebP-версия; если нет — конвертирует
.jpg/.jpeg/.png в
.webp и сохраняет в отдельный кэш, откуда при следующих
запросах отдаёт уже готовый файл. Возвращает URL: либо на
.webp-версию (конвертация удалась), либо на оригинальный
файл (формат не поддерживается, лимит времени исчерпан или конвертация
не удалась).
Все параметры необязательны, передаются по позиции через запятую:
85).1000) —
общий бюджет времени на конвертацию для всей страницы: как
только суммарное время рендера страницы превышает порог, модификатор
перестаёт конвертировать новые файлы (в том числе для других тегов
|webp на этой же странице) и просто отдаёт оригинал — это
защищает страницу от замедления, если разом нужно сконвертировать много
ещё не закэшированных картинок.UPLOAD_TIME) — если оно задано и найдено, перед
нами динамический файл (обычная загруженная через
админку/пользователем картинка), путь к которому строится по дате
загрузки, как и у |path. Если передать сюда пустую
строку, модификатор переключается в режим статического
файла шаблона — путь строится относительно
templates/{шаблон}/, без привязки к дате.FILE_NAME) — в динамическом режиме это ключ в переданном
массиве ({ROW:FILE_NAME}); в статическом — сам путь к
файлу, буквально, относительно templates/{шаблон}/.Модификатор понимает как одну запись (ассоциативный массив с полями даты/имени файла), так и список записей (галерея) — во втором случае вернётся список готовых URL, по одному на каждый элемент.
Динамический файл (обычная загруженная картинка — поля по умолчанию, параметры не нужны):
{*IMG}
<picture>
<source srcset="{IMG|webp}" type="image/webp">
<img src="{IMG:UPLOAD_TIME|path}{IMG:FILE_NAME}" class="card-img-top p-2">
</picture>
{IMG*}Статический файл шаблона (не привязан к дате —
третий параметр пустой, четвёртый — путь к файлу относительно
templates/{шаблон}/):
<picture>
<source srcset="{NULL|webp:80,1000,,/images/melbis_shop.png}" type="image/webp">
<img src="{PATH}/images/melbis_shop.png" class="card-img-top p-2">
</picture> Здесь {NULL} используется как тег-«носитель»: самому
модификатору не нужно реальное значение переменной, весь путь к файлу
задан параметрами.
В обоих примерах <source type="image/webp">
предлагает браузеру WebP-версию, а обычный <img> —
гарантированный запасной вариант на случай, если браузер WebP не
поддерживает или картинка ещё не сконвертирована.
Парсер позволяет пропустить значение переменной через любую доступную функцию PHP (если она не заблокирована в целях безопасности).
Поскольку запятая, двоеточие, |, {,
} и пробел используются самим парсером как служебные
разделители, передать их буквально в параметр (например, разделитель в
split или значение в style у tag)
можно через специальные подстановки:
| Подстановка | Символ |
|---|---|
_nl_ |
перевод строки |
_sp_ |
пробел |
_cl_ |
: |
_cm_ |
, |
_pl_ |
| |
_bo_ |
{ |
_bc_ |
} |
Например, {TEXT|split:_cm_,1} разобьёт строку по
буквенной запятой (а не по служебной), а
{VAR|tag:span,,font-family: Arial_cm_ sans-serif} вставит
настоящую запятую в значение style.
Как передаются аргументы:
|) всегда автоматически становится первым аргументом
вызываемой функции.:,
разбиваются по запятой , и передаются в функцию как второй,
третий и последующие аргументы.Синтаксис:
{ПЕРЕМЕННАЯ|имя_функции:параметр2,параметр3}
Примеры использования:
{PRICE|round} — Вызовет round($PRICE).
Округлит 15.7 до 16.{TITLE|mb_strtoupper} — Вызовет
mb_strtoupper($TITLE). Переведет строку в верхний
регистр.{EMAIL|md5} — Вызовет md5($EMAIL). Удобно
для генерации хэшей (например, для Gravatar).{PRICE|round:1} — Вызовет
round($PRICE, 1). Оставит один знак после запятой.{ARTICLE|trim:.} — Вызовет
trim($ARTICLE, '.'). Удалит точки в начале и в конце
строки.{TEXT|strip_tags:<b><a>} — Вызовет
strip_tags($TEXT, '<b><a>'). Удалит все теги,
кроме разрешенных <b> и <a>.Практически важный случай, который из общего правила
не очевиден: {QUERY|rawurlencode} — кодирование для
сегмента пути, в отличие от [QUERY] (см. «Синтаксис
шаблонов»).
Передача массива в аргумент вызова модуля.
Сериализуйте массив в PHP, а в шаблон передавайте готовую строку —
модуль-приёмник объявит параметр типа serial, и парсер сам
развернёт её обратно в массив:
$filters_line = serialize($filters);
MELBIS()->TplAssign($tpl, 'FILTERS', $filters_line);{MELBIS:goods_navi([TOTAL],[PAGE_NUM],[FILTERS])}Квадратные скобки обязательны: сериализованная строка полна кавычек,
двоеточий и фигурных скобок, и без urlencode разбор списка
аргументов сломается. Обратный urldecode парсер делает сам
при разборе serial-параметра.
Сериализуйте именно в PHP, а не модификатором в шаблоне:
TplAssign приводит ключи любого массива к верхнему
регистру, поэтому serialize внутри тега сохранит ключи как
ORDER, PRICE, а не исходные
order, price.
⚠️ Регистр в параметрах, если они — ключи массива: У
штатных PHP-функций параметры передаются буквально, как вы их
написали — парсер их не ищет в контексте и не приводит к
верхнему регистру (в отличие от
calc/print/array_item, где
параметр — это имя переменной, которую движок сам находит в
UPPERCASE-контексте). Если параметр функции — это ключ, по которому она
сама лезет внутрь строки массива (как второй аргумент
array_column), он должен совпадать с реальным регистром
ключей ваших данных, а они, пройдя через TplAssign, всегда
в UPPERCASE:
{STORE|array_column:id|join} — не сработает, вернёт пустую строку: array_column ищет ключ 'id',
а в строках STORE ключ называется 'ID'
{STORE|array_column:ID|join} — сработает: регистр параметра совпадает с реальным ключом
Это не то же самое правило, что регистр параметров у
calc/print/array_item (там
причина — поиск переменной движком), просто оба случая на практике
требуют писать параметр заглавными буквами.
Для сложной бизнес-логики (например, перевод строк, мультивалютность,
специфическое форматирование) вы можете регистрировать собственные
функции. Они вызываются через модификатор, начинающийся со знака
$ (например, |$trans).
Механизм коллбэков использует строгую регистрацию и передает все данные в функцию в виде одного ассоциативного массива, что позволяет гибко комбинировать переменные шаблона и системные настройки.
У вас есть два уровня регистрации: глобальный и локальный (уровень конкретного модуля).
DefineCallback): Пишет в общий
реестр ядра, который при подключении копируется в каждый юнит, — поэтому
колбэк доступен всем модулям, включая вложенные субмодули. Достаточно
зарегистрировать его один раз в модуле верхнего уровня: присоединять
библиотеку к каждому вложенному модулю, где используется модификатор, не
нужно (см. «Модули-библиотеки»). Регистрировать нужно на верхнем
уровне библиотеки или модуля (а не в теле функции): верхний
уровень выполняется при подключении на каждом запросе, тогда как функция
модуля на отдаче из кэша не запускается.MELBIS()->DefineCallback('trans', 'MELBIS_INC_translate', ['from' => 'en']);UnitCallbackCustom): Вызывается из тела конкретного модуля
(после его подключения). Добавляет функцию или переопределяет настройку
исключительно для текущего модуля — на субмодули не
распространяется.MELBIS()->UnitCallbackCustom('trans', 'MELBIS_INC_translate', ['from' => 'ru']);UnitCallbackSet и
UnitCallbackGet для динамического изменения дефолтных
параметров прямо по ходу выполнения скриптаВ шаблоне вы указываете алиас (со знаком $) и, при
необходимости, через запятую перечисляете дополнительные
аргументы. Аргументами могут выступать как ключи из текущего
массива данных, так и статичные строки или числа.
Синтаксис:
{ОСНОВНАЯ_ПЕРЕМЕННАЯ|$алиас:АРГ_1,АРГ_2}
Пример:
{PRICE|$discount:GROUP_ID,10,USD} (где
PRICE и GROUP_ID — переменные из базы данных,
а 10 и USD — статичный текст, переданный прямо
из верстки).
Парсер использует гибридную модель передачи данных. В вашу функцию приходит один массив, который содержит данные сразу в двух форматах: по универсальным числовым индексам и по строковым ключам.
Структура массива на примере
{PRICE|$discount:GROUP_ID,10,USD}:
[
// === Универсальные числовые индексы ===
0 => 1500, // Индекс 0 ВСЕГДА содержит главное значение тега {PRICE}
1 => 5, // Значение переменной GROUP_ID (нашлось в текущих данных)
2 => '10', // Статичная строка (так как ключа '10' нет в данных)
3 => 'USD', // Статичная строка
// === Строковые ключи ===
'price' => 1500, // Дубликат главного значения по имени тега
'group_id' => 5,
'usd' => 'USD',
'from' => 'ru' // Подтянулось из дефолтных настроек PHP (см. ниже)
](💡 Примечание: парсер умно защищает числовые индексы — статичный
аргумент 10 не создаст строковый ключ '10',
чтобы не сломать нумерацию).
🔥 Наложение приоритетов для строковых ключей (от низшего к высшему): Сборка ассоциативной части массива происходит с наложением приоритетов:
['from' => 'en', 'color' => 'black']| и помещает её в массив.
Пример:
['from' => 'en', 'title' => 'Значение']FROM), который
совпадает с дефолтной настройкой PHP, значение из HTML-шаблона
полностью перезапишет дефолтное.Таким образом, современные функции могут просто обращаться к
$mParam[0], $mParam[1], не привязываясь к
тому, как переменная называлась в шаблоне, а сложные функции могут
управлять бизнес-логикой через переопределение строковых ключей.