Шаблони

Шаблони

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