Переменные сайта
Переменные сайта — плоский словарь «имя → значение», который хранится у сайта и подставляется в готовый HTML при рендере страницы. Это способ не вписывать название магазина, телефон и адрес поддержки в каждый блок руками.
Как завести переменную
Заголовок раздела «Как завести переменную»В интерфейсе: сайт → Переменные сайта. Строка = имя + значение, переменных может быть сколько угодно.
Имя обязано подходить под шаблон ^[a-zA-Z][a-zA-Z0-9_]*$: латинская буква
в начале, дальше латиница, цифры и подчёркивание. Кириллица, дефис, точка и пробел
не допускаются — форма подсветит ошибку, а бэкенд молча выбросит такую пару
при сохранении.
Значение — всегда строка. Типов нет: число, true и дата хранятся текстом
и подставляются как текст. Частый случай — держать в переменной адрес логотипа
или иконки, загруженных в хранилище сайта.
Через API переменные — часть настроек сайта, отдельного эндпоинта у них нет:
PUT /api/sites/{id}Content-Type: application/json
{ "variables": { "shop_name": "Магазин", "phone": "+7 900 000-00-00" } }Поле variables заменяет словарь целиком, а не дополняет его: чтобы удалить
переменную, отправьте объект без неё. {} очищает все переменные, отсутствие
поля — не меняет ничего.
Как использовать
Заголовок раздела «Как использовать»В любом тексте пишете @имя:
<footer> {{ props.title }} — @shop_name, телефон @phone</footer>Работает и в шаблоне блока, и в значениях полей блока, и в шаблоне макета — подстановка идёт по итоговому HTML, поэтому объявлять переменную в схеме блока не нужно, и в контекст Liquid она не попадает.
Порядок такой:
- Liquid рендерит шаблон блока → HTML.
- По этому HTML прогоняется замена
@имя→ значение. - Шаблон макета рендерится Liquid и оборачивает блоки.
- По итоговому HTML макета замена
@имяпрогоняется ещё раз.
Внутри Liquid-шаблона макета переменные дополнительно доступны как
{{ site.variables.имя }}, рядом с {{ site.name }}. В шаблоне блока такого
доступа нет — только @имя.
Важно: @ в шаблонах небезопасен
Заголовок раздела «Важно: @ в шаблонах небезопасен»Замена — это регулярное выражение по всему HTML, а не аккуратная подстановка известных имён. Правило одно и жёсткое:
Если у сайта задана хотя бы одна переменная, любая последовательность
@словов итоговом HTML будет заменена: на значение — если имя совпало, на пустую строку — если нет. Предупреждения не будет.
Что из этого ломается на практике:
| В шаблоне | Что получится |
|---|---|
info@example.com |
info.com — @example съеден |
@media (max-width: 600px) в CSS макета или блока |
(max-width: 600px) — правило разваливается |
@keyframes, @font-face, @import |
то же самое |
@click, @input (синтаксис Vue/Alpine) |
атрибут теряет имя |
CSS блока попадает под замену не всегда: он проходит через неё, когда страница собирается с макетом (макет вставляет CSS блоков в свой шаблон, а замена идёт по результату). Если сайт публикуется без макета, CSS уезжает провайдеру отдельным полем и остаётся нетронутым. Полагаться на это не стоит — макет может появиться позже.
Как жить:
- пока у сайта нет ни одной переменной, замена не выполняется вовсе;
- нужны медиазапросы и почта в тексте — не заводите переменные на этом сайте
либо выносите такой CSS/текст туда, где
@не встречается; - почту собирайте из частей:
{{ props.user }}@{{ props.domain }}или через HTML-сущность@.
Что видно в предпросмотре
Заголовок раздела «Что видно в предпросмотре»Редактор страницы подставляет переменные тем же способом, что и сервер, —
предпросмотр показывает реальные значения. В редакторе блока переменные
не подставляются: там блок рендерится вне контекста сайта, и @имя останется
текстом.
Ошибки и особенности
Заголовок раздела «Ошибки и особенности»- Неизвестное имя → пустая строка, без сообщения в логе и без пометки в HTML.
- Значение подставляется как есть, без экранирования: HTML внутри значения попадёт в страницу разметкой.
- Переменные не участвуют в условиях Liquid внутри блока — на момент рендера шаблона их ещё нет.
Источники
Заголовок раздела «Источники»backend/src/Entity/Site.php— полеvariablesbackend/src/Service/Site/UpdateSiteService.php— валидация имён, полная замена словаряbackend/src/Publishing/BlockRenderer.php—applyVariables()backend/src/Publishing/LayoutRenderer.php— контекстsite.variables, повторная заменаbackend/src/Publishing/Provider/FourCmsProvider.php— что уходит провайдеру с макетом и безfront/src/lib/placeholder.ts,front/src/components/SiteVariablesModal.tsx— предпросмотр и форма