Шаблоны
Шаблоны
Шаблон в Celena — набор .tpl-файлов в каталоге templates/<slug>/. PHP в .tpl запрещён (теги <?php/<?= экранируются как текст) — используются только теги шаблонизатора. Это безопасно, удобно для вёрстки и легко документируется.
При первом обращении .tpl компилируется в PHP и кешируется в storage/cache/tpl/. Инвалидация — автоматически по времени изменения файла.
Синтаксис
Переменные
{title} <!-- $vars['title'], авто-экранирование -->
{user.name} <!-- доступ по точке -->
{news.body|raw} <!-- без экранирования (доверенный HTML) -->
Inline-теги
Тег с параметрами — это вызов обработчика:
{include file="_partials/head.tpl"}
{lang key="hello.world"}
{csrf} <!-- скрытое поле -->
{csrf format="meta"} <!-- <meta name="csrf-token"> для AJAX -->
{icon name="check" size="20"} <!-- inline SVG-иконка -->
{plugin_assets} <!-- CSS/JS активных плагинов -->
В параметрах разрешена интерполяция {var}:
{lang key="greeting" name="{user.name}"}
Условия
[if {user.role}="admin"]
Привет, начальник.
[else if {user.role}="editor"]
Привет, редактор.
[else]
Гость.
[/if]
[if {is_published}] <!-- truthy-проверка -->
Опубликовано
[/if]
Операторы: =, !=, >, <, >=, <=. Сравнения >/< — числовые, остальные — строковые. Можно сравнивать две переменные: [if {a}={b}]…[/if].
Циклы
[foreach var="news" as="n"]
<article>
<h2><a href="{n.url}">{n.title}</a></h2>
<small>{n.date} · {n.author}</small>
</article>
[/foreach]
Служебные переменные внутри цикла:
| Переменная | Значение |
|---|---|
{_index} | 0-based номер итерации |
{_total} | всего элементов |
{_first} | "1" если первый, иначе "" |
{_last} | "1" если последний |
Если массив пуст — тело не рендерится. Циклы и условия можно вкладывать друг в друга.
Комментарии
{* Этот текст в вывод не попадёт *}
Структура темы
templates/mytheme/
├── theme.json манифест темы
├── home.tpl главная
├── page.tpl обычная страница
├── news_list.tpl список новостей
├── news_full.tpl одна новость
├── search.tpl поиск
├── 404.tpl ошибка 404
├── _partials/ переиспользуемые куски (head, header, footer)
└── assets/ CSS/JS темы
Переменные, которые ядро передаёт всегда
{site.name} {site.url}
{page.title} {page.seo_title} {page.seo_description} {page.og_image}
{locale} {canonical_self}
{account.is_guest} {account.name}
Защита <script> и <style>
Содержимое <script>/<style> защищено от парсинга блочных тегов (CSS-селекторы вроде [data-x] не примутся за теги). При этом inline-теги {lang …} внутри скриптов работают — чтобы переводить JS-генерируемую разметку.
Async-блоки
Тяжёлую секцию можно догружать отдельным запросом после рендера страницы:
{async block="latest_news" url="/api/blocks/latest_news" placeholder="Загрузка…"}
Параметры: trigger (load/visible/manual), poll (30s/5m), class. После загрузки контейнер получает класс is-loaded.
Запреты
<?php,<?=— экранируются как текст.- Прямая работа с БД/сессиями/файлами из шаблона — нельзя (только через зарегистрированные теги или async-блоки).
- Сторонние CDN запрещены (CSP). Все ассеты — в
templates/<slug>/assets/.