N1 Nex1on

Главный шаблон сайта на тегах

Главный шаблон — рамка каждой страницы: шапка, меню, место для содержимого, боковая колонка и подвал. Пишется обычной разметкой с тегами, без 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

На этой странице
Поделиться: Telegram WhatsApp
Откладывать можно и без входа: закладки сохранятся в этом браузере, а после входа их можно перенести в учётную запись. Вход
Обсуждение

Комментарии

Обсуждение ещё не началось

Пока никто не высказался. Будьте первым.

Пожаловаться на запись