# Шаблоны

Шаблон в Celena — набор `.tpl`-файлов в каталоге `templates/<slug>/`. **PHP в `.tpl` запрещён** (теги `<?php`/`<?=` экранируются как текст) — используются только теги шаблонизатора. Это безопасно, удобно для вёрстки и легко документируется.

При первом обращении `.tpl` компилируется в PHP и кешируется в `storage/cache/tpl/`. Инвалидация — автоматически по времени изменения файла.

## Синтаксис

### Переменные

```html
{title}                <!-- $vars['title'], авто-экранирование -->
{user.name}            <!-- доступ по точке -->
{news.body|raw}        <!-- без экранирования (доверенный HTML) -->
```

### Inline-теги

Тег с параметрами — это вызов обработчика:

```html
{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}`:

```html
{lang key="greeting" name="{user.name}"}
```

### Условия

```html
[if {user.role}="admin"]
  Привет, начальник.
[else if {user.role}="editor"]
  Привет, редактор.
[else]
  Гость.
[/if]

[if {is_published}]            <!-- truthy-проверка -->
  Опубликовано
[/if]
```

Операторы: `=`, `!=`, `>`, `<`, `>=`, `<=`. Сравнения `>`/`<` — числовые, остальные — строковые. Можно сравнивать две переменные: `[if {a}={b}]…[/if]`.

### Циклы

```html
[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"` если последний |

Если массив пуст — тело не рендерится. Циклы и условия можно вкладывать друг в друга.

### Комментарии

```html
{* Этот текст в вывод не попадёт *}
```

## Структура темы

```
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-блоки

Тяжёлую секцию можно догружать отдельным запросом после рендера страницы:

```html
{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/`.
