Головний шаблон сайту на тегах
Головний шаблон — рамка кожної сторінки: шапка, меню, місце для вмісту, бічна колонка й підвал. Пишеться звичайною розміткою з тегами, без PHP.
Головний шаблон — рамка кожної сторінки: шапка, меню, місце для вмісту, бічна колонка й підвал. Покладіть файл layouts/main.tpl.html у views/ своєї теми (themes/<ім'я>/views/layouts/main.tpl.html), і сторінка будується за ним. Файлу немає або він зламаний — працює звичайний вигляд, сайт не ламається. <head>, скрипти рушія та кнопка «нагору» лишаються від рушія: стилі й шрифти підключайте через theme.json і assets.
Готовий зразок: шапка, меню, колонка, підвал
<header class="site-head"><div class="wrap">
<a class="brand" href="{home}"><span class="brand-name">{site_name}</span></a>
{languages} {search}
[if:user.logged]<a href="{user.url}">{user.name}</a> {logout_button}[else]<a href="{user.login_url}">Увійти</a>[/if]
</div><div class="wrap"><nav class="nav">[each:menu]<a href="{item.url}">{item.title}</a>[/each]</nav></div></header>
<main id="content" class="wrap has-side">
<div>{content}</div>
<aside class="side-col region region--side">{region:sidebar}</aside>
</main>
<footer class="site-foot"><div class="wrap">© {year} {site_name}</div></footer>Класи site-head, wrap, brand, nav, has-side, side-col, site-foot — готові класи спільного оформлення рушія: з ними зразок одразу виглядає як частина сайту й підлаштовується під кольори теми.
Що видно на телефоні (390). Колонка йде під вміст, пошук розкривається під шапкою. Меню розділів у зразку вище на телефоні не показується: кнопка меню в нього не ввійшла. Тепер для неї є тег {menu_toggle}: поставте його в шапку замість рядка <nav class="nav">…[each:menu]…</nav> — на телефоні з’явиться кнопка «Меню».
Що виводять теги
| Тег | Що виводить | Приклад |
|---|---|---|
{site_name} | назву сайту з «Налаштування → Загальні» | <a href="{home}">{site_name}</a> |
{home} | адресу головної | <a href="{home}"> |
{year} | поточний рік | © {year} |
{locale} | код мови сторінки | {locale} |
{canonical} | основну адресу цієї сторінки | <link rel="canonical" href="{canonical}"> |
{theme} | адресу теки файлів теми (assets) | <img src="{theme}/img/logo.svg"> |
{content} | вміст сторінки (запис, магазин, форум…) у контейнері рушія: не вилазить за ширину екрана, годиться для кабінету, форуму й форм | <main>{content}</main> |
{content_raw} | той самий вміст без обгортки й без обмеження ширини: лише для власних повносторінкових розкладок; для кабінету, форуму й форм беріть {content} | <div class="full">{content_raw}</div> |
{languages} | вибір мови (готовий блок) | {languages} |
{search} | рядок пошуку (готовий блок) | {search} |
{login} | блок «Увійти / Реєстрація» або імʼя користувача, що увійшов (готовий) | {login} |
{poll} | поточне опитування сайту | {poll} |
{logout_button} | кнопку «Вийти» з ключем захисту | [if:user.logged]{logout_button}[/if] |
{menu_toggle} | кнопку «Меню» та меню розділів, яке на телефоні відкривається кнопкою | {menu_toggle} |
{user_menu} | меню учасника: профіль, повідомлення, панель, вихід | [if:user.logged]{user_menu}[/if] |
{region:header}, {region:before_content}, {region:sidebar}, {region:after_content}, {region:footer}, {region:head_actions} | блоки модулів, поставлені в це місце теми | <aside>{region:sidebar}</aside> |
[each:menu]…[/each] | пункти меню сайту; всередині {item.title}, {item.url}, {item.active} | [each:menu]<a href="{item.url}">{item.title}</a>[/each] |
Про відвідувача, що увійшов
| Тег | Що виводить | Приклад |
|---|---|---|
[if:user.logged]…[else]…[/if] | різний текст гостю й тому, хто увійшов | [if:user.logged]Привіт![else]Увійдіть[/if] |
{user.name}, {user.url} | імʼя та адресу профілю | <a href="{user.url}">{user.name}</a> |
{user.avatar} | адресу аватара; порожньо, якщо аватара немає | [if:user.avatar]<img src="{user.avatar}">[/if] |
{user.role} | назву ролі | {user.role} |
{user.pm_unread} | кількість непрочитаних особистих повідомлень; порожньо, якщо модуль вимкнено | [if:user.pm_unread]Листів: {user.pm_unread}[/if] |
{user.favorites_count} | кількість закладок | {user.favorites_count} |
{user.pm_url}, {user.favorites_url} | адреси повідомлень і закладок | <a href="{user.pm_url}">Повідомлення</a> |
{user.admin_url}, [if:user.can_admin]…[/if] | адресу панелі й умову «до панелі пускають» | [if:user.can_admin]<a href="{user.admin_url}">Панель</a>[/if] |
{user.login_url}, {user.register_url}, {user.forgot_url} | адреси входу, реєстрації, відновлення | <a href="{user.register_url}">Реєстрація</a> |
Де ми і хто прийшов
Враховуються лише ті теги, на які посилається файл: сторінка без них нічого не витрачає.
| Тег | Що виводить | Приклад |
|---|---|---|
{page.title}, {page.description} | назву й опис цієї сторінки (як у <head>) | <h1>{page.title}</h1> |
{page.route}, [if:page.home] | імʼя маршруту сторінки й умову «це головна» | [if:page.home]…[else]…[/if], [if:page.route=news.show]…[/if] |
{page.path} | адресу сторінки без домену | {page.path} |
[if:module.ім'я] | модуль увімкнено (будь-яке імʼя з теки modules) | [if:module.shop]<a href="/shop">Магазин</a>[/if] |
{category.title}, {category.url}, {category.key} | поточну рубрику, якщо модуль її назвав | [if:category.title]<a href="{category.url}">{category.title}</a>[/if] |
[each:crumbs] {item.title} {item.url} [if:item.last] | хлібні крихти: «Головна» + ланцюжок модуля (або пункт меню цієї сторінки); останній пункт позначено last | [each:crumbs][ifnot:item.last]<a href="{item.url}">{item.title}</a> › [else]{item.title}[/ifnot][/each] |
{visitor.country} | код країни відвідувача («UA»); із заголовка CDN або локальної бази адрес; порожньо, якщо невідома | [if:visitor.country=UA]…[/if] |
[if:visitor.mobile], [if:visitor.tablet], [if:visitor.desktop], {visitor.device} | тип пристрою за рядком браузера | [if:visitor.mobile]{menu_toggle}[/if] |
{propose_url} | посилання «Запропонувати запис»; порожньо, якщо модуль або налаштування вимкнено | [if:propose_url]<a href="{propose_url}">Запропонувати запис</a>[/if] |
{social_login} | готові кнопки «Увійти через …» (лише ввімкнені мережі; ключів застосунку на сторінці немає); порожньо, якщо мереж немає | <div class="soc">{social_login}</div> |
[if:social.google], {social.google.url}, {social.google.title} | вхід через конкретну мережу (google, github, yandex, vk): чи ввімкнена, адреса початку входу й назва — кнопку можна поставити у власну розмітку | [if:social.google]<a class="btn-g" href="{social.google.url}">{social.google.title}</a>[/if] |
[if:social.any] | чи ввімкнена бодай одна мережа | [if:social.any]або[/if] |
{social_profile} | блок «Прив’язані сервіси» для кабінету: привʼязати й відвʼязати за паролем; гостю порожньо | {social_profile} |
{user.field:ім'я} | власне поле профілю користувача, що увійшов (поле заводить власник); гостю, вимкненому й неіснуючому полю — порожньо; значення екранується | <p>Місто: {user.field:city}</p> |
Рубрику й ланцюжок розділів називає модуль: кладе в спільні дані вигляду (View::share) ключ pageContext — ['category' => ['title' => '…', 'url' => '/r/…', 'key' => '…'], 'crumbs' => [['title' => '…', 'url' => '/…']]] — або додає їх фільтром theme.page_context. Адреса береться лише власна («/…»).
Умови й повтори
[if:ім'я]…[/if] — показати, якщо значення є; [ifnot:ім'я]…[/ifnot] — якщо немає; [if:ім'я=значення]…[else]…[/if] — порівняння; [each:список]…[/each] — повтор за списком із {item}, {item.ключ}, {index}. Значення з даних сторінки доступні за іменем; у кожного вигляду свої (сторінка «Вигляди на тегах»).
Безпека
PHP, include і виклик функцій у файлі тегів не працюють; розмітка очищається за білим списком (без script, style, iframe, обробників подій і data-*); адреси лише http(s)://, /шлях, #; до посилань із шаблону рушій додає rel="noopener". Значення екрануються. Межі: 20000 знаків, 400 тегів, вкладеність 6, повторів 60.
Обновлено 16.10.2026
Пока никто не высказался. Будьте первым.