Шаблони
Шаблони
Шаблон у 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/.