Как AVE.cms собирает сайт
Эта глава объясняет публичную модель AVE.cms: что такое шаблон сайта, рубрика, поле, документ, навигация, запрос, блок и каталог, как они связаны и в каком порядке превращаются в готовую HTML-страницу.
Общая схема
URL
-> документ
-> рубрика
-> поля документа
-> шаблон рубрики
-> [tag:maincontent]
-> шаблон сайта
-> блоки и модули
-> запросы
-> навигации
-> SEO и хлебные крошки
-> готовый HTML
У каждой сущности одна основная зона ответственности:
| Сущность | Назначение |
|---|---|
| Шаблон сайта | Общая HTML-оболочка: head, шапка, подвал и места для компонентов. |
| Тема | Статические CSS/JS, изображения, шрифты и порядок их подключения. |
| Рубрика | Тип контента: набор полей, правила URL, права и способ вывода одного документа. |
| Поле | Контракт отдельного значения: редактор, валидация, хранение и публичный вывод. |
| Документ | Конкретная запись рубрики со своим URL, состоянием, SEO и значениями полей. |
| Навигация | Независимое дерево ссылок на документы и произвольные URL. |
| Запрос | Сохраненная выборка документов с условиями, сортировкой и шаблоном списка. |
| Блок | Переиспользуемый фрагмент разметки или логики. |
| Каталог | Иерархия разделов, назначение документов, характеристики, фильтры и листинги. |
| Модуль | Устанавливаемое расширение с маршрутами, тегами, таблицами, hooks и интерфейсом. |
Практические руководства
Если вы впервые работаете с системой или хотите понять новый редактор целиком, начните с подробной главы Content Studio: от рубрики до публикации.
| Раздел панели | Руководство |
|---|---|
| Документы | Создание, публикация, URL, ревизии и системные страницы |
| Рубрики и поля | Проектирование типа контента, формы и публичного вывода |
| Шаблоны | Внешняя оболочка сайта, теги, кеш и ревизии |
| Twig-компоненты | Точечные модульные вставки и границы их применения |
| Темы | CSS, JavaScript, изображения, шрифты и ZIP-пакеты темы |
| Блоки | Переиспользуемые фрагменты, редакторы и параметры |
| Навигация | Шаблоны уровней, пункты и сборка HTML |
| Запросы | Выборки документов, группы условий и шаблоны списка |
| Каталог | Универсальные деревья разделов, поля и фильтры |
Медиа, поля и модули вынесены в отдельные главы: Медиа и миниатюры, Поля документов и Модульная система.
Основной публичный сайт собирается встроенными сущностями AVE.cms. Twig не заменяет шаблоны сайта, рубрик и запросов. Для сложных модульных компонентов он подключается через обычный зарегистрированный тег; подробности приведены в отдельной главе.
Три уровня шаблонов
В AVE.cms слово «шаблон» используется для трех связанных, но разных уровней.
1. Шаблон сайта
Шаблон сайта содержит весь HTML-документ:
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>[tag:title]</title>
<meta name="description" content="[tag:description]">
<meta name="robots" content="[tag:robots]">
<link rel="canonical" href="[tag:canonical]">
[tag:rubheader]
</head>
<body>
<header class="site-header">
[tag:navigation:main]
</header>
<main class="site-main">
[tag:maincontent]
</main>
<footer class="site-footer">
[tag:sysblock:footer]
</footer>
[tag:rubfooter]
</body>
</html>
Главный контракт шаблона сайта — тег [tag:maincontent]. В него движок
подставляет результат шаблона рубрики текущего документа или HTML системной
страницы модуля.
Шаблон сайта обычно содержит:
<html>,<head>и<body>;- SEO-теги текущего документа;
- общую шапку и подвал;
- теги подключения CSS и JavaScript активной темы;
- основную и вспомогательные навигации;
- общие блоки и модульные компоненты;
[tag:rubheader]и[tag:rubfooter]для точечных вставок рубрики.
Шаблон сайта не должен знать полный набор полей новости, товара или статьи. Этим владеет рубрика.
2. Основной шаблон рубрики
Основной шаблон рубрики описывает содержимое одного документа:
<article class="article">
<header class="article__header">
<h1>[tag:doc:document_title]</h1>
<time>[tag:docdate]</time>
</header>
<div class="article__lead">[tag:fld:lead]</div>
<div class="article__image">[tag:fld:image]</div>
<div class="article__content">[tag:fld:content]</div>
</article>
После обработки полей этот HTML становится [tag:maincontent] внешнего
шаблона сайта.
3. Дополнительный шаблон рубрики
Документ может выбрать альтернативный вариант вывода той же рубрики. Например, у рубрики «Статьи» могут быть шаблоны:
- обычная статья;
- лонгрид;
- фотогалерея;
- промостраница.
Набор полей и правила рубрики остаются общими, меняется только композиция конкретного документа.
Рубрика
Рубрика — это тип контента, а не папка документов. Примеры рубрик:
- Новости;
- Статьи;
- Страницы;
- Товары;
- Сотрудники;
- Вопросы и ответы.
Рубрика определяет:
- набор и группы полей;
- порядок и ширину полей в редакторе документа;
- значения полей по умолчанию;
- основной и дополнительные публичные шаблоны;
- шаблон тизера для элементов запросов;
- внешний шаблон сайта;
- шаблон формирования URL новых документов;
- права групп пользователей;
- Open Graph, вставки в header и footer;
- код и hooks до и после сохранения документа.
Например, рубрика «Новости» может содержать поля image, lead, content,
source и gallery. Все документы этой рубрики используют один контракт
данных, поэтому запросы и шаблоны могут обращаться к полям по стабильным alias.
Подробнее о типах, настройках и хранении значений: Поля документов.
Документ
Документ — конкретная запись выбранной рубрики. Он хранит:
- ID и рубрику;
- название и заголовок хлебных крошек;
- alias и историю URL;
- публикацию, удаление и срок действия;
- автора и даты;
- анонс;
- SEO, robots, ключевые слова и теги;
- значения полей рубрики;
- выбранный дополнительный шаблон рубрики;
- связи с каталогами и модулями.
Документ предоставляет данные, но не должен самостоятельно описывать всю внешнюю оболочку сайта.
URL документа
Рубрика может формировать alias по шаблону:
news/%year/%month/%alias
Для документа с коротким alias company-opened-office результатом будет:
/news/2026/07/company-opened-office
Меню не участвует в формировании URL. После изменения alias прежний адрес может остаться в истории редиректов и вести на новый URL.
Навигация
Навигация — независимое дерево ссылок. Она хранит:
- пункты и уровни вложенности;
- связь с документом или произвольный URL;
- название, описание, target и изображение;
- CSS-класс и дополнительные атрибуты;
- доступность группам пользователей;
- шаблоны обычного и активного пункта каждого уровня.
Навигация вставляется в страницу по alias:
[tag:navigation:main]
Как собирается HTML навигации
Шаблоны навигации применяются в строгом порядке:
Обёртка: начало
Уровень 1: начало
Обычный или активный пункт уровня 1
...
Уровень 1: конец
Обёртка: конец
Для вложенного меню шаблон пункта родительского уровня должен содержать место вывода следующего уровня:
<!-- Уровень 1: обычный пункт -->
<li>
<a href="[tag:link]">[tag:linkname]</a>
[tag:level:2]
</li>
<!-- Уровень 2: обычный пункт -->
<li>
<a href="[tag:link]">[tag:linkname]</a>
[tag:level:3]
</li>
Уровень N: начало задаёт обёртку списка. Тег [tag:content] внутри неё
заменяется готовыми пунктами уровня. Если тег не указан, пункты добавляются
после начальной разметки. Уровень N: конец всегда выводится после всех пунктов
уровня. Поля Обёртка: начало и Обёртка: конец выводятся один раз вокруг
всего дерева.
Пример настроек первого уровня:
<!-- Обёртка: начало -->
<nav class="site-navigation" aria-label="Основная навигация">
<!-- Уровень 1: начало -->
<ul class="site-navigation-list">[tag:content]
<!-- Уровень 1: конец -->
</ul>
<!-- Обёртка: конец -->
</nav>
Результат будет иметь полную структуру
<nav><ul>...пункты...</ul></nav>. Если в навигации нет доступных пунктов,
внешние обёртки не выводятся.
Удаление пункта меню не удаляет документ и не отключает его URL. Один документ может находиться в нескольких меню или не входить ни в одно.
Запросы
«Запрос» в AVE.cms — не HTTP-запрос, а сохраненная выборка документов. Он отвечает на два вопроса:
- Какие документы выбрать?
- Как вывести список и каждый его элемент?
Запрос может задавать:
- одну или несколько рубрик;
- простые и вложенные группы условий;
- сочетания
ИиИЛИ; - сортировку;
- лимит и пагинацию;
- шаблон элемента;
- обертку списка;
- настройки кеширования.
Примеры запросов:
- последние новости;
- популярные статьи;
- материалы текущего автора;
- связанные документы;
- акции;
- товары с заданными свойствами.
Тег запроса использует ID или alias:
[tag:request:latest_news]
Условия с разной логикой должны быть сгруппированы явно:
Опубликован
И
(
Рубрика = Новости
ИЛИ
Рубрика = Статьи
)
И
(
Тег = Важное
ИЛИ
Просмотры > 1000
)
Система сначала выбирает документы, затем применяет к каждому шаблон элемента и объединяет элементы в обертку списка.
Блоки
Блок — переиспользуемый фрагмент, который можно вставлять в шаблон сайта, шаблон рубрики, запрос или другой блок.
Примеры:
- контакты в подвале;
- баннер;
- форма подписки;
- предупреждение;
- преимущества;
- сложный компонент с PHP-логикой.
[tag:sysblock:product_card]
[tag:sysblock:contacts]
Блоки могут содержать запросы, навигации, модульные теги и условия. Для новой логики предпочтительнее передавать сложные операции в сервисы и модули, оставляя в блоке композицию и небольшие проектные условия.
Каталог
Каталог — отдельный слой над рубриками, документами и полями. Он не равен магазину и не должен предполагать, что каждый проект содержит товары.
Каталог можно использовать для:
- товарного каталога;
- новостного портала;
- базы знаний;
- каталога услуг;
- библиотеки документов;
- базы специалистов или организаций;
- любого структурированного раздела с фильтрацией.
Место каталога в системе
Рубрики и поля
|
v
Документы
|
v
Каталог
|- разделы и вложенность
|- назначенные документы
|- наборы характеристик
|- фильтры и условия
|- сортировка
|- шаблон карточки и листинга
`- индекс для быстрого публичного поиска
Рубрика отвечает за структуру одного документа. Каталог отвечает за то, где и как множество документов показывается пользователю.
Что хранит каталог
- собственное название и назначение;
- корневые и вложенные разделы;
- документы каждого раздела;
- используемые поля и группы полей;
- поля, включенные по умолчанию для новых разделов;
- фильтры и их порядок;
- условия показа разделов и документов;
- настройки сортировки и пагинации;
- конфигурацию карточки и листинга;
- проекцию данных для быстрого публичного чтения.
Каталог и запросы
Обычный запрос подходит для независимой подборки: последние новости, работы автора, акции или связанные статьи.
Каталог нужен, когда дополнительно требуются:
- постоянная иерархия разделов;
- назначение документов разделам;
- фасетные фильтры;
- согласованные карточки;
- управляемая сортировка;
- быстрый индекс большого набора документов.
Запросы и каталог дополняют друг друга. Например, главная страница может показывать запрос «Новинки», а переход в раздел открывает полноценный каталог с фильтрами.
Товарные возможности
Товары являются расширением универсального каталога. Модуль товаров добавляет:
- артикул, цену, старую цену и наличие;
- товарные характеристики;
- варианты одного товара;
- карточки товара;
- товарную индексацию.
Корзина, заказы, оплаты и доставки принадлежат отдельным модулям. Их физическое удаление не должно удалять документы, рубрики и универсальную структуру каталога.
Как выводится раздел каталога
- По URL определяется каталог и его раздел.
- Загружаются настройки раздела, набор полей и фильтров.
- Входные значения фильтров нормализуются и проверяются.
- Индекс выбирает подходящие документы.
- Применяются сортировка и пагинация.
- Для каждого документа собирается карточка.
- Карточки объединяются в листинг.
- Результат вставляется в публичную страницу каталога.
Карточка является отдельным управляемым шаблоном. Она не должна копироваться в несколько системных блоков, иначе главная, каталог и подборки начинают выглядеть и работать по-разному.
Индексация и кеш каталога
Публичный фильтр не должен каждый раз разбирать все JSON-значения полей. После сохранения документа его данные проецируются в индекс каталога. Индекс содержит только значения, нужные для листинга, сортировки и фильтрации.
Перестроение требуется после изменения:
- документа или его полей;
- назначения документа разделам;
- набора характеристик;
- настроек фильтров;
- конфигурации карточки;
- структуры вариантов товара.
Модули
Модуль — физически отделяемое расширение AVE.cms. Он может добавить:
- собственные публичные и административные маршруты;
- теги для шаблонов, рубрик и блоков;
- новые типы полей;
- hooks и события;
- таблицы и миграции;
- настройки и права;
- пункт в меню панели управления;
- действие в шапке, уведомления и Dashboard-виджет;
- фоновые web-задачи и интеграции с внешними сервисами.
Где модуль участвует в сборке
До поиска документа PublicKernel загружает только включенные публичные части
установленных модулей. После этого возможны три основных сценария.
- Собственный маршрут. Модуль полностью отвечает на URL и завершает запрос без документа. Так работают API, callbacks и файловые endpoints.
- Страница в оболочке сайта. Модуль предоставляет
[tag:maincontent], но использует выбранный шаблон сайта, SEO и общий публичный pipeline. - Встроенный компонент. Модуль регистрирует тег, который встречается в шаблоне сайта, рубрики, запроса или блока.
Например, форма обратной связи может зарегистрировать тег:
[tag:module:contacts:feedback]
Шаблон отвечает только за место компонента. Валидация, отправка и хранение данных принадлежат модулю.
Зависимости и жизненный цикл
Файлы доступны
-> установка миграций и прав
-> модуль включен
-> маршруты, меню, hooks и теги работают
- Отключение прекращает загрузку runtime-вкладов, но сохраняет данные.
- Деинсталляция выполняет объявленный модулем сценарий и убирает права.
- Физическое удаление возможно только для отделяемого пакета после деинсталляции.
- Зависимости не позволяют выключить модуль, пока от него зависит другой включенный пакет.
Ядро, рубрики и документы не должны напрямую подключать PHP-файлы модуля. Взаимодействие строится через его публичные сервисы, теги, маршруты и hooks.
Подробнее: Модульная система.
Порядок сборки публичной страницы
Фактический pipeline одного публичного запроса:
PublicKernelзапускает framework, сессию, авторизацию, модули, защиту и hooks.- Проверяются прямые публичные маршруты модулей.
- URL разбирается на alias, пагинацию и дополнительные параметры.
- По alias находится документ.
- Если документа нет, проверяется история редиректов, затем загружается документ 404.
- Вместе с документом загружаются рубрика, права и внешний шаблон сайта.
- Проверяется полный кеш страницы.
- Выполняется настроенный публичный код рубрики перед загрузкой документа.
- Проверяются публикация документа и право текущей группы на чтение.
- Основной или дополнительный шаблон рубрики заполняется полями документа.
- Полученный HTML вставляется в
[tag:maincontent]шаблона сайта. - Подставляются header, Open Graph и footer рубрики.
- Обрабатываются поля запроса, блоки, системные блоки и тизеры.
- Обрабатываются теги установленных модулей.
- Выполняются сохраненные запросы.
- Формируются навигации.
- Подставляются SEO, данные документа, хлебные крошки и системные пути.
- Выполняется разрешенный PHP из хранимых шаблонов.
- Результат проходит через hooks ответа.
- Для администратора добавляются быстрое редактирование и публичный debug.
- Готовый HTML отправляется браузеру и при необходимости сохраняется в кеш.
При попадании в полный кеш часть внутренних шагов не выполняется повторно, но логическая структура результата остается той же.
Кеширование
Публичный runtime использует несколько уровней:
| Уровень | Что хранится |
|---|---|
| Snapshot документа | Нормализованные свойства документа и значения полей. |
| Шаблон документа | Результат заполнения шаблона рубрики. |
| Полная страница | Шаблон сайта вместе с содержимым и компонентами. |
| Запрос | Результат тяжелой выборки или листинга. |
| Каталог | Проекция для фильтрации, сортировки и карточек. |
Ключи учитывают документ, рубрику, шаблон, группу пользователя, версии полей и пагинацию. После сохранения документа, рубрики, поля, запроса, шаблона или конфигурации каталога связанные записи должны инвалидироваться.
Подробнее: Кеш базы и контента.
Hooks публичного pipeline
Hook — именованная точка вмешательства в работу системы. Модуль подписывает обработчик на событие и получает структурированный контекст. Это позволяет добавлять проектную логику без изменения ядра.
Основные публичные точки
frontend.request.received
frontend.route.resolved
content.document.loading
content.document.loaded
content.rubric.loading
content.rubric.loaded
content.query.loading
content.query.loaded
content.query.rendering
content.query.rendered
content.template.rendering
content.template.rendered
frontend.response.rendering
frontend.response.rendered
События loading позволяют подготовить или заменить источник до чтения.
События loaded получают уже загруженный объект и могут дополнить результат.
События rendering и rendered работают с содержимым до и после рендера.
Сохранение документов
Для административного и API-сохранения предусмотрены отдельные стадии:
content.document.saving
content.document.saved
content.document.created
content.document.updated
content.document.published
content.document.unpublished
content.document.deleting
content.document.deleted
content.document.snapshot_built
Точные названия доступных событий и их контексты показываются в каталоге hooks. Обработчик должен проверять рубрику, ID или состояние документа и быстро завершаться, если событие ему не подходит.
Примеры применения:
- опубликовать новую статью в Telegram или Дзен;
- передать заказ во внешнюю CRM;
- проверить сертификат товара перед публикацией;
- дополнить документ данными внешнего API;
- поставить задачу на перестроение поискового индекса;
- очистить CDN или сторонний кеш после изменения страницы.
Hooks полей
Тип поля сам отвечает за нормализацию и валидацию значения, но модуль может подписаться на общий цикл поля:
content.field.normalizing
content.field.normalized
content.field.validating
content.field.validated
content.field.saving
content.field.saved
content.field.rendering
content.field.rendered
Обработчик обязательно ограничивается alias, ID или типом поля. Иначе он будет запускаться для каждого поля каждого документа.
Каталог и hooks
Индекс каталога обновляется вслед за сохранением документа и его snapshot,
поэтому интеграции могут использовать фактические события
content.document.saved и content.document.snapshot_built. Инвалидация
проходит через cache.invalidating и cache.invalidated.
Устанавливаемый каталоговый или товарный модуль может объявить дополнительные
события через hook_definitions. Их имена и контекст становятся частью
контракта именно этого модуля и появляются в общем каталоге hooks. Использовать
необъявленное имя как системный контракт нельзя.
Изменение и отмена результата
LifecycleEvent может вернуть измененный результат. Отмена поддерживается
только на стадиях, где это явно заявлено контрактом. При сохранении документа
для контролируемого отказа используется DocumentSaveEvent::fail(). Ошибка
должна быть понятной и не оставлять частично сохраненные данные.
Для побочных действий после сохранения предпочтительна стадия saved. Для
валидации и запрета операции используется стадия до записи. Внешний HTTP-вызов
не следует выполнять внутри длинной транзакции, если его можно отложить до
успешного сохранения.
Полный каталог, приоритеты, форматы контекста и отладка: Хуки и события.
Практический порядок создания сайта
- Создать внешний шаблон сайта с
[tag:maincontent]. - Создать рубрики для реальных типов контента.
- Добавить и расположить поля каждой рубрики.
- Собрать основной шаблон рубрики и необходимые альтернативы.
- Создать документы и заполнить значения полей.
- Настроить alias и проверить историю редиректов.
- Создать навигации и привязать документы или URL.
- Создать запросы для лент и связанных материалов.
- Вынести повторяемые части в блоки.
- При необходимости создать каталог, его разделы, поля и фильтры.
- Установить только нужные проекту модули.
- Проверить права, SEO, 404, пагинацию, кеш и мобильный вывод.
Типовые композиции
Новостной сайт
Рубрики: Новости, Статьи, Страницы
Запросы: Последние, Популярные, По теме
Каталог: необязателен; может использоваться как рубрикатор публикаций
Модули: RSS, формы, авторизация — по необходимости
База знаний
Рубрики: Инструкции, FAQ, Справочные страницы
Каталог: разделы знаний и фильтры по продукту/версии
Запросы: Обновленные, Связанные, Популярные
Навигация: основное меню и дерево документации
Интернет-магазин
Рубрики: Товары, Страницы, Новости
Каталог: товарные разделы, характеристики и фильтры
Модуль товаров: цены, наличие, варианты и карточки
Commerce: корзина, заказы, избранное и история просмотров
Gateways: оплаты, авторизация и доставки отдельными пакетами
Частые ошибки
- Размещать всю разметку документа во внешнем шаблоне сайта.
- Использовать меню для формирования URL документа.
- Копировать одну карточку в несколько системных блоков.
- Использовать длинную цепочку
И/ИЛИбез групп условий. - Делать каталог зависимым от товаров и корзины.
- Читать JSON всех полей при каждом публичном фильтре вместо индекса каталога.
- Помещать большую бизнес-логику в хранимый шаблон вместо сервиса или модуля.
- Забывать инвалидировать кеш после изменения шаблона, поля или каталога.