Виды на тегах: как переделать страницу без PHP
Любой вид сайта (главную, вход, регистрацию, поиск, кабинет, страницу) можно заменить файлом тегов. Это обычная HTML-разметка, в которую вставляются теги {имя}, условия … и повторы [each:список]…[/each] (общий язык тегов, тот же…
Любой вид сайта (главную, вход, регистрацию, поиск, кабинет, страницу) можно заменить файлом тегов. Это обычная HTML-разметка, в которую вставляются теги {имя}, условия [if:имя]…[/if] и повторы [each:список]…[/each] (общий язык тегов, тот же, что в «Новости → Шаблоны записей»).
Как включить
В вашей теме положите файл по пути вида с окончанием .tpl.html вместо .php:
| Что заменяете | Файл в теме |
|---|---|
| главная разметка (шапка, места, содержимое, подвал) | themes/<имя>/views/layouts/main.tpl.html |
| страница сайта | themes/<имя>/views/pages/show.tpl.html |
| вход | themes/<имя>/views/auth/login.tpl.html |
| регистрация, восстановление пароля, сброс, второй фактор, подтверждение почты, правила | auth/register.tpl.html, auth/forgot.tpl.html, auth/reset.tpl.html, auth/two-factor.tpl.html, auth/verify.tpl.html, auth/rules.tpl.html |
| поиск | search.tpl.html |
| кабинет, безопасность, сеансы, приватность | auth/profile.tpl.html, auth/profile-security.tpl.html, auth/profile-sessions.tpl.html, auth/profile-privacy.tpl.html |
| публичный профиль | auth/public-profile.tpl.html |
Нет файла тегов или он сломан (например, не закрыт блок) — работает обычный PHP-вид, страница не ломается. Файл тегов в общей папке темы главнее вида модуля, как и PHP-файл.
Главная разметка: пример в 15 строк
<header class="my-head">
<a href="{home}">{site_name}</a>
[each:menu]<a href="{item.url}">{item.title}</a> [/each]
{languages} {search}
[if:user.logged]<a href="{user.url}">{user.name}</a>[else]<a href="{user.login_url}">Войти</a>[/if]
</header>
<main>{content}</main>
<aside>{region:sidebar}</aside>
<footer>© {year} {site_name}</footer>Положите это в themes/<имя>/views/layouts/main.tpl.html — и страница получит вашу шапку с меню, выбором языка, поиском и входом, содержимое, боковую колонку и подвал. <head>, скрипты движка и кнопка «наверх» остаются от движка; стили и шрифты подключаются через theme.json и assets — в файле тегов их писать не нужно.
Общие теги любой страницы
| Тег | Что выводит |
|---|---|
{site_name} | название сайта |
{locale} | язык страницы |
{year} | текущий год |
{home} | адрес главной |
{canonical} | основной адрес этой страницы |
{theme} | путь к папке темы |
{user.logged} | условие: посетитель вошёл ([if:user.logged]…[/if]) |
{user.name}, {user.url} | имя вошедшего и адрес его профиля |
{user.login_url} | адрес страницы входа |
{user.avatar} | адрес аватара; пусто, если аватара нет (для вёрстки [if:user.avatar]…[/if]) |
{user.role} | название роли вошедшего |
{user.pm_unread} | число непрочитанных личных сообщений; пусто, если модуль «Сообщения» выключен |
{user.favorites_count} | число закладок |
{user.pm_url}, {user.favorites_url} | адреса личных сообщений и закладок |
{user.admin_url}, [if:user.can_admin]…[/if] | адрес панели и условие «в панель пускают» (пусто, если нет) |
{user.register_url}, {user.forgot_url} | адреса регистрации и восстановления пароля |
{logout_button} | готовая кнопка «Выйти» с ключом защиты (выход у нас — форма, ссылкой нельзя из-за ключа) |
{menu_toggle} | кнопка «Меню» и меню разделов (то, что на телефоне открывается кнопкой) |
{user_menu} | меню участника: профиль, сообщения, панель, выход |
{login} | готовый блок входа и регистрации |
{content} | содержимое страницы в контейнере движка (не вылезает за ширину экрана); для кабинета, форума и форм берите его |
{content_raw} | содержимое без обёртки и без ограничения ширины, только для своих полностраничных раскладок |
{languages} | выбор языка |
{search} | строка поиска |
{poll} | текущий опрос |
{region:header}, {region:before_content}, {region:sidebar}, {region:after_content}, {region:footer}, {region:head_actions} | блоки модулей, поставленные в это место темы |
[each:menu]…[/each] | пункты меню сайта; внутри {item.title}, {item.url}, {item.active} |
Теги из данных вида, условия, повторы
Дальше идут данные, которые вид получил от движка: {имя}, {a.b}, [each:список] с {item}, {item.ключ}, {index}, условия [if:имя], [if:имя=значение], [ifnot:имя], опция limit=N. Секретное (ключи защиты форм, пароли, токены, сеансы) и объекты через теги не отдаются.
Виды ядра на тегах
| Вид | Что доступно (кроме общих тегов) |
|---|---|
auth/login | {form} — готовая форма входа; слова {t.eyebrow}, {t.title}, {t.lead}, {t.forgot}, {t.no_account}, {t.submit} и другие; {forgot_url}, {register_url}; условие [if:can_register] |
auth/register | {form}, слова {t.…} (приставка auth.register), {forgot_url} |
auth/forgot, auth/reset, auth/two-factor, auth/verify, auth/rules | у каждого {form} и слова {t.…} (приставки auth.forgot, auth.reset, auth.2fa, auth.verify, auth.rules) |
search | {form} (строка поиска), {query}, [each:results] ({item.title}, {item.url}, {item.excerpt}…), [each:popular], {found.*}, [if:tooShort], {minimum}, слова {t.…} (search.*) |
auth/profile, auth/profile-security, auth/profile-sessions, auth/profile-privacy | {form} (и {form:2}, {form:3} — остальные формы вида по порядку), {identity} (шапка кабинета), {profile_nav} (меню кабинета), слова {t.…} (profile.*) |
auth/public-profile | {identity} и данные профиля |
pages/show | {title}, {page.title}, {page.excerpt}, {page.body} (текст страницы, разметка движка), {cover}, [each:trail], [each:children], [each:siblings] |
Форма по частям
В видах с формой (вход, регистрация, восстановление, сброс пароля, второй фактор, подтверждение почты, правила, поиск, кабинет) форму можно вывести целиком тегом {form} — это безопасный путь, или собрать по частям, чтобы расставить поля в нужном порядке:
| Тег | Что выводит |
|---|---|
{form_open} | открытие формы с её адресом и скрытыми полями; ключ защиты — там |
{field:имя} | поле целиком: подпись, подсказка, ошибка, как построил движок; имя — это name у поля ввода |
{field:captcha} | проверка «не робот» |
{submit} | кнопка отправки |
{form_close} | закрытие формы |
{form_open}
{field:email}
{field:password}
{field:captcha}
{submit}
{form_close}Поле, которого нет в вашем шаблоне, в форме не появится: расстановка — выбор темы. Обязательные поля и проверку «не робот» не опускайте — без них форма не пройдёт проверку.
Слово {t.хвост} даёт подпись интерфейса «<приставка вида>.<хвост>» на языке посетителя, поэтому тексты в шаблоне на разные языки не дублируются.
Обсуждение (комментарии) на тегах
Файл views/comments/thread.tpl.html темы заменяет вид обсуждения под записью, страницей и другими материалами. Нет файла или он не прошёл проверку — работает обычный вид.
| Тег | Что выводит |
|---|---|
[each:comments] … [/each] | комментарии плоским списком в порядке показа: ответ идёт сразу за своим комментарием, глубину даёт {item.level} (0 — корень) |
{item.id} {item.name} {item.avatar} {item.profile} {item.date} | номер (для якоря), имя автора, адрес аватара, адрес профиля (пусто, если закрыт), дата |
{item.text} | текст участника: разметка движка, очищенная (скриптов и чужих тегов нет); у спрятанного человеком из «Кого я не вижу» пуст |
{item.likes} {item.minus} {item.rating} {item.verified} {item.op} | «Полезно» (число) или оценка «+ / −» (число «за» минус «против»; {item.minus} — оценка отрицательная), звёзды отзыва, «проверенный покупатель», «автор записи» |
{item.place} {item.group} {item.online} {item.signature} | поля карточки автора, если их включил владелец (место, группа, «на сайте», подпись) |
{item.image1} {item.image2} {item.image3} | картинки комментария (миниатюры) |
{item.actions} | готовые кнопки движка: «Полезно», «Ответить», «Цитата», «Изменить», «Удалить», «Не видеть», «Пожаловаться» — правила показа те же, что в обычном виде |
{compose} | форма комментария целиком (поля, ловушка для роботов, ключ защиты) и скрипт ответа |
{form_open} {field:body} {field:author_name} {field:author_email} {submit} {form_close} | та же форма по частям — вёрстка ваша, ключ защиты и скрытые поля остаются у движка |
{follow} | кнопка «Следить за комментариями» (вошедший с подтверждённой почтой — сразу, гость называет почту и подтверждает письмом); пусто, если подписку выключил владелец |
{comments_script} | скрипт «Ответить»/«Цитата»/звёзды отдельно (внутри {compose} и {form_close} он уже есть) |
{pager} {report} {notice} | постраничная навигация, «Пожаловаться на запись», сообщение вместо формы (обсуждение закрыто, предел, нужен вход) |
{comments.total} [if:closed] [if:can_write] | число комментариев; обсуждение закрыто; писать можно |
Пример:
<section id="comments"><h2>{comments.word}: {comments.total}</h2>
[each:comments]
<article id="comment-{item.id}" class="c c-l{item.level}"><b>{item.name}</b> <time>{item.date}</time>
<div>{item.text}</div><footer>{item.actions}</footer></article>
[/each]
{pager}
[if:can_write]{compose}[else]{notice}[/if]
</section>Списки с отбором, архив, метки, рубрики и числа сайта (модуль «Новости»)
Эти теги работают в любом файле тегов: в главной рамке, на странице, в ленте. Отбор записан в самом имени списка парами «ключ:значение» через двоеточие; несколько значений — через «_». Ключи защиты, почта и закрытое в списки не попадают; записи отбираются тем же запросом, что и лента (права, пароль, язык, срок действия).
| Список | Что даёт | Отбор в имени |
|---|---|---|
[each:news_list category=films,3 limit=5 sort=views] … [/each] (или привычно [each:news_list:cat:3_5:limit:5:sort:views]) | записи | |
[each:comments_list limit=5 category=3] (или [each:comments_list:limit:5:cat:3]) | последние комментарии к записям (у вошедшего в {item.name} его имя) | limit, category, not_category, author (номера или логины), days, post (номера записей) |
[each:news_archive:limit:12] | месяцы архива | limit |
[each:news_tags:limit:30] | облако меток | limit |
[each:news_categories] | рубрики деревом (родитель, затем вложенные) | category (какие рубрики; номер, адрес, список), not_category (кроме), subcat — yes с вложенными, no только названные, only только вложенные, depth — сколько уровней, limit |
В элементе news_list: {item.id} {item.title} {item.url} {item.excerpt} {item.date} {item.cover} {item.cover_large} {item.category} {item.category_url} {item.by} (автор, если сайт показывает авторов) {item.views} {item.rating} {item.rating_count} {item.comments} {item.pinned} {item.locked} (запись под паролем: видно только название) {item.first} {index}. В comments_list: {item.name} {item.text} (до 160 знаков, без разметки) {item.url} {item.date} {item.title} (название записи) {item.avatar}. В news_archive: {item.title} {item.url} {item.count}. В news_tags: {item.title} {item.url} {item.count} {item.weight} (1–5, для размера шрифта). В news_categories: {item.title} {item.url} {item.count} {item.active} (текущая рубрика) {item.level} (0 — верхний уровень) {item.parent} {item.id} [if:item.has_children].
Числа сайта: {stat.news} {stat.news_day} {stat.news_week} {stat.news_month}, то же для comments и users ({stat.comments_week}, {stat.users_month}).
Пример «Рубрики с числом записей» и «Популярное за месяц»:
<nav><ul>
[each:news_categories]<li class="l{item.level}"><a href="{item.url}">{item.title}</a> <small>{item.count}</small></li>[/each]
</ul></nav>
<h3>Популярное</h3>
[each:news_list:days:30:sort:views:limit:5]<p><a href="{item.url}">{item.title}</a> · {item.views}</p>[/each]
<p>Записей: {stat.news}, за неделю: {stat.news_week}</p>«Загрузки» на тегах
Шаблон под рубрику. Новости, «Загрузки», форум (раздел) и магазин (категория) называют рубрику страницы движку (адрес рубрики латиницей, цифрами и дефисом, до 40 знаков). Тогда файл <вид>.<адрес-рубрики>.tpl.html (например, views/news/show.tech.tpl.html или views/forum/section.api.tpl.html) берётся раньше общего <вид>.tpl.html; для остальных рубрик остаётся общий. Описание рубрики страницы (без разметки) модуль тоже отдаёт в общие данные страницы; тег {category.description} подключает ядро. Обрезка текста в тегах записи: limit=N знаков, words=N слов, wordsafe=1 — по границе слова.
Файлы views/downloads/index.tpl.html (каталог и рубрика) и views/downloads/show.tpl.html (страница релиза) темы заменяют PHP-виды модуля. Скачивание идёт обычными адресами движка: счётчик, ограничение доступа и пароли работают как раньше.
| Вид | Тег | Что выводит |
|---|---|---|
| каталог | [each:cards] | релизы: {item.title} {item.url} {item.description} {item.version} {item.date} {item.cover} {item.category} {item.category_url} {item.hits} {item.first} |
| каталог | [each:rubrics] | рубрики: {item.title} {item.url} {item.count} {item.active} |
| каталог | {category.title} {category.url} {category_description} {pager} {t.empty} | рубрика страницы (от рамки), её описание, листание, слово «пусто» |
| релиз | {item.title} {item.description} {item.version} {item.hits} {item.changelog} {item.requirements} {date} {cover} {cover_large} | сам релиз |
| релиз | {category.title} {category.url} {files.count} [if:allow_download] | рубрика, число файлов, «есть что скачать» |
| релиз | [each:files] | файлы: {item.name} {item.url} (адрес скачивания) {item.platform} {item.arch} {item.size} {item.ext} {item.hits} {item.primary} {item.external} (хост внешней ссылки) |
| релиз | [each:sums] | контрольные суммы: {item.name} {item.checksum} — чтобы проверить скачанное |
Пример страницы релиза:
<h1>{item.title}</h1><p>v{item.version} · {date} · скачано {item.hits}</p>
[if:allow_download]
[each:files]<p><a href="{item.url}">{item.name}</a> {item.platform} {item.arch} {item.size} ↓{item.hits}</p>[/each]
[/if]
<h2>Что нового</h2><p>{item.changelog}</p>
<h2>Требования</h2><p>{item.requirements}</p>
[each:sums]<code>{item.name}: {item.checksum}</code>[/each]Баннеры на тегах
В любом файле тегов баннер ставится по номеру или целым местом. Правила показа те же, что у обычных баннеров: срок, расписание, устройство, страницы, роли, страны, «только первая страница».
| Тег | Что выводит |
|---|---|
{banner:5} | баннер с номером 5 (номер — в списке баннеров панели) |
{banner_place:sidebar} | все баннеры места целиком; места: topbar, header, before_content, sidebar, after_content, footer, between_feed (между записями ленты), between_comments (между комментариями) |
Места between_feed и between_comments рисуют сами виды новостей и комментариев: баннер идёт после каждой третьей записи ленты и после каждого пятого комментария. У баннера в панели отмечаются роли (guest — гость), страны (RU, UA — только в них; -BY — везде, кроме) и «только на первой странице раздела». Страница, где есть такой баннер, не уходит в общий кэш: ответ зависит от зрителя.
Каталог вставок: любой элемент модуля — одним тегом
Каждый модуль объявляет всё, что можно вынести на любую страницу и вставить в любое место файла тегов темы: готовые блоки, списки для своей вёрстки, числа, формы и кнопки. Это единый каталог: из него строятся вкладка «Вывод на сайте» в панели модуля (таблица элементов, параметры, пример и кнопка «Копировать», файлы видов), подсказки редактора шаблонов и эта таблица.
Как вставляется:
- блок, форма, кнопка, число —
{block:модуль.имя параметр=значение}:{block:news.count what=news period=week}; параметров до четырёх; - список для своей вёрстки —
[each:list:модуль_имя:параметр:значение:…] … {item.поле} … [/each]:[each:list:news_latest:cat:3:sort:views:limit:5]; несколько значений — через «_», в имени списка «модуль_имя» (точка в имени тега не годится).
Правило для модуля: элемент вида block, button и form сам отвечает за экранирование своего вывода (через e() и виды движка, как любой вид); число и текст (value) — только экранированный текст без разметки; список отдаёт строки, они экранируются тегами. Каталог проверяет параметры, но чужую разметку не чистит. Параметры проверяются по описанию элемента: число — в границах, выбор — только из списка, номера — только цифры; лишнее отбрасывается. Сбой, право, которого нет, превышение времени или размера — пустая вставка, страница цела. Старые теги (news_list…, {banner:5}, [each:comments]) продолжают работать.
Как модуль объявляет элемент (фильтр theme.blocks, запись «модуль.имя» → module, kind (block, list, value, form, button), title, description, params, items, example, works_in, permission, render) — описано в core/Themes/BlockCatalog.php. Готовые блоки раскладки модулей (то, что модуль кладёт в места темы) попадают в каталог сами — их вид в таблице помечен «блок». Таблица ниже собирается скриптом php dev/katalog-spravka.php из каталога, руками не пишется.
| Модуль | Элемент | Вид | Что выводит | Вставка | Параметры |
|---|---|---|---|---|---|
| banners | banners.after_content | блок | Баннеры под содержимым | {block:banners.after_content} | — |
| banners | banners.banner | блок | Один баннер | {block:banners.banner} | id |
| banners | banners.before_content | блок | Баннеры над содержимым | {block:banners.before_content} | — |
| banners | banners.footer | блок | Баннеры в подвале | {block:banners.footer} | — |
| banners | banners.header | блок | Баннеры в шапке | {block:banners.header} | — |
| banners | banners.place | блок | Баннеры места | {block:banners.place place=sidebar} | place (topbar/header/before_content/sidebar/after_content/footer/between_feed/between_comments) |
| banners | banners.sidebar | блок | Баннеры в боковой колонке | {block:banners.sidebar} | — |
| banners | banners.topbar | блок | Баннеры в полосе над шапкой | {block:banners.topbar} | — |
| comments | comments.thread | блок | Обсуждение под записью | {block:comments.thread} | — |
| content | content.facts | блок | Детали | {block:content.facts} | — |
| content | content.vakansii_home | блок | Вакансии | {block:content.vakansii_home} | — |
| downloads | downloads.home | блок | Файлы на главной | {block:downloads.home} | — |
| downloads | downloads.latest | блок | Последние файлы | {block:downloads.latest} | — |
| downloads | downloads.releases | список | Последние релизы | [each:list:downloads_releases:limit:5]{item.title}[/each] | limit |
| events | events.home | блок | Ближайшие события | {block:events.home} | — |
| favorites | favorites.star | блок | Закладка | {block:favorites.star} | — |
| forms | forms.form | форма | Форма | {block:forms.form} | id |
| forum | forum.home | блок | Обсуждения на главной | {block:forum.home} | — |
| forum | forum.latest | блок | Последние обсуждения | {block:forum.latest} | — |
| forum | forum.topics | список | Последние темы | [each:list:forum_topics:limit:5]{item.title}[/each] | limit |
| gallery | gallery.home | блок | Из галереи | {block:gallery.home} | — |
| highlight | highlight.script | блок | Подсветка кода | {block:highlight.script} | — |
| news | news.archive | список | Архив по месяцам | [each:list:news_archive:limit:12]{item.title}[/each] | limit |
| news | news.archive_box | блок | Блок «Архив» | {block:news.archive_box} | — |
| news | news.categories | список | Рубрики деревом | [each:list:news_categories]{item.title}[/each] | — |
| news | news.comments | список | Последние комментарии | [each:list:news_comments:limit:5]{item.name}[/each] | limit, cat |
| news | news.count | число/текст | Число | {block:news.count what=news period=all} | what (news/comments), period (all/day/week/month) |
| news | news.feed_box | блок | Блок «Лента» | {block:news.feed_box} | — |
| news | news.latest | список | Записи с отбором | [each:list:news_latest:limit:5:start:0:sort:new]{item.id}[/each] | limit, start, cat, user, days, tag, main, sort (new/old/title/views/rating/rand) |
| news | news.latest_box | блок | Блок «Последние новости» | {block:news.latest_box} | — |
| news | news.rss | кнопка | Кнопка RSS | {block:news.rss} | — |
| news | news.suggest | кнопка | Кнопка «Предложить запись» | {block:news.suggest} | — |
| news | news.tags | список | Облако меток | [each:list:news_tags:limit:30]{item.title}[/each] | limit |
| pages | pages.list | блок | Страницы | {block:pages.list} | — |
| polls | polls.current | блок | Опрос | {block:polls.current} | — |
| polls | polls.one | блок | Один опрос | {block:polls.one} | id |
| registry | registry.latest | блок | Последняя версия движка | {block:registry.latest} | — |
| reviews | reviews.home | блок | Отзывы клиентов | {block:reviews.home} | — |
| share | share.after | блок | Кнопки «поделиться» | {block:share.after} | — |
| shop | shop.cart | кнопка | Корзина | {block:shop.cart} | — |
| shop | shop.cart_icon | блок | Значок корзины | {block:shop.cart_icon} | — |
| shop | shop.categories_tiles | блок | Категории плитками | {block:shop.categories_tiles} | — |
| shop | shop.latest | блок | Новинки | {block:shop.latest} | — |
| shop | shop.products | список | Новые товары | [each:list:shop_products:limit:4]{item.title}[/each] | limit |
| shop | shop.showcase | блок | Витрина магазина | {block:shop.showcase} | — |
| subscribe | subscribe.compact | блок | Подписаться на новости | {block:subscribe.compact} | — |
| subscribe | subscribe.form | блок | Рассылка | {block:subscribe.form} | — |
| tags | tags.cloud | блок | Метки | {block:tags.cloud} | — |
| tags | tags.subject | блок | Метки | {block:tags.subject} | — |
Безопасность
- Формы рисует только движок: в файле тегов тег
<form>вычищается, поэтому ключ защиты и поля всегда на месте. Форму выводит{form}. - Разметка шаблона очищается по белому списку: без
script,style,iframe, обработчиков событий и атрибутовdata-*; адреса толькоhttp(s)://,/путь,#. - Значения экранируются по месту (в тексте, в атрибуте, в адресе по-разному).
- Пределы те же, что у языка тегов: размер шаблона 20000 знаков, 400 тегов, вложенность 6, повторов 200.
- Письма в файлах тегов не нужны: их тексты правятся в «Почта → тексты писем».
Доп. поля новостей: где работают (после переноса в «Доп. поля»)
Поля заводятся в разделе «Доп. поля» (хозяин «Новости», можно ограничить рубриками). Пустое поле нигде не показывается: ни значение, ни подпись.
| Где | Что писать | Условие |
|---|---|---|
| Полная запись | {field:имя}, {fieldlabel:имя}, [if:field:имя], {fieldurl:имя} | поле видно этому читателю |
Карточка ленты (index.tpl.html, [each:cards]) | {item.field:имя}, {item.fieldlabel:имя}, {item.fieldurl:имя}, [if:item.field:имя] | галочка «в списке»; закрытой записи (под паролем) полей нет |
Списки и блоки ([each:news_list …], [each:list:news_latest], {block:news.latest_box}) | те же теги с item. | то же |
| Отбор записей | [each:news_list field:год>2000 field:жанр=драма], custom=имя (заполнено), custom=имя is=значение | поле с галочкой «фильтр» (иначе список пуст, а не вся лента) |
| Значение ссылкой («Режиссёр: Нолан» → все записи с этим значением) | автоматически на странице записи; в списках — <a href="{item.fieldurl:имя}">{item.field:имя}</a>; адрес вида /news/рубрика?field=имя&value=значение | галочки «фильтр» и «значение ссылкой»; виды: строка, список-выбор, число, дробь |
| Поиск в панели | строка поиска по списку записей находит значения полей | галочка «поиск» |
| RSS | к описанию записи добавляется «Подпись: значение» | галочка «отдавать в RSS»; только публичные поля |
| Замена по сайту | «Поиск и замена» видит значения полей новостей | право на замену |
Адрес с field=…&value=… показывает над лентой плашку «Подпись: значение» и кнопку «Сбросить отбор». Закрытые поля (только для персонала, по ролям) тегами и в RSS не отдаются.
«Предложить запись» на тегах (модуль «Новости»)
Файлы темы: views/news/suggest.tpl.html (форма для вошедшего) и views/news/suggest-login.tpl.html (гостю: пояснение и кнопки входа). Нет файла — страница как раньше.
Форма пишется движком (ключ защиты, ловушка от роботов, проверка): целиком — {form}, либо по частям {form_open} … {form_close}:
| Тег | Что это |
|---|---|
{field:title}, {field:excerpt}, {field:category}, {field:tags}, {field:body} | основные поля; поле, которого нет в шаблоне, в форме не окажется (заголовок и текст обязательны — без них форма не пройдёт) |
{field:f_имя} | своё дополнительное поле: только то, которое владелец отметил в «Доп. поля» галочками «в форме сайта» и «заполняет посетитель»; привязанное к рубрике показывается, когда выбрана она; картинки, файлы и видео посетителю не даются |
{submit} | кнопка отправки |
{t.title} {t.lead} {t.note} {t.send} {t.mine} {t.too_many} | слова страницы на языке посетителя |
{left}, [if:can_send] | сколько предложений осталось за сутки; можно ли ещё отправлять |
{mine_url} | адрес «Мои предложения» |
[each:categories] | рубрики для выбора: {item.id} {item.title} |
Страница для гостя: {login_url}, {register_url}, [if:can_register], слова {t.guest_title} {t.guest_text} {t.guest_login} {t.guest_register}.
Обновлено 16.10.2026
Пока никто не высказался. Будьте первым.