Шаблоны
Шаблон страницы в Templite — это полный Blade-документ (от <!DOCTYPE html> до </html>), который описывает HTML-каркас страницы и место для блоков. Каждая страница привязана к одному шаблону через pages.template_page_id.
Структура
Запись в БД (template_pages)
| Колонка | Назначение |
|---|---|
slug | Уникальный идентификатор шаблона |
name | Отображаемое название |
settings | JSON с произвольными настройками шаблона |
screen | FK на files — скриншот шаблона для UI |
Связанные таблицы:
block_tabs,block_sections,block_fields— поля шаблона через polymorphic-связь (fieldable_type = TemplatePage::class). Та же иерархия Tab → Section → Field, что у блоков.template_page_library— pivot шаблон ↔ внешние JS/CSS-библиотеки.page_types,pages— обратные связи: какие типы страниц и какие конкретные страницы используют этот шаблон.
Файлы на диске
Код шаблона хранится в storage/cms/templates/<slug>/:
storage/cms/templates/default/
├── template.blade.php — Blade-каркас страницы (обязательно)
├── style.scss — стили шаблона (опционально)
└── script.js — JS-логика (опционально)WARNING
В отличие от блоков и компонентов, шаблоны страниц существуют только в storage/cms/templates/. Аналога app/Templates/ нет, BlockRegistry-подобный реестр для шаблонов не реализован. Все шаблоны живут в одной директории.
Рендер страницы через шаблон
Алгоритм PageRenderer:
Рендерит все блоки страницы → собирает HTML-строку.
Если у страницы есть
templatePage, ищетstorage/cms/templates/<slug>/template.blade.php.Если файл существует — регистрирует Blade view namespace
cms_template_<slug>на этот путь.Рендерит через
cms::render.page-wrapper:blade@extends($__template_view) @section('blocks') {!! $__blocks_content !!} @endsectionТо есть ваш шаблон расширяется обёрткой, которая заполняет секцию
blocksготовым HTML блоков.Если у страницы нет привязки к
templatePageили файл шаблона отсутствует — fallback на встроенный layoutcms::layouts.page.
Переменные в шаблоне
В template.blade.php доступны:
| Переменная | Содержимое |
|---|---|
$page | Eloquent-модель Page (с relations, attributes, SEO) |
$global | Значения глобальных настроек |
$breadcrumbs | Иерархия хлебных крошек (массив для рендера) |
$assets | Скомпилированные ресурсы страницы: css, js, cdn_css[], cdn_js[] |
$lang | Текущий язык страницы |
$hreflang | Готовый HTML-блок с <link rel="alternate" hreflang="..."> для мультиязычности |
Структура $assets
[
'css' => 'https://example.com/storage/cms/assets/page-42.css', // или null
'js' => 'https://example.com/storage/cms/assets/page-42.js', // или null
'cdn_css' => [
'https://cdn.example.com/swiper.min.css',
],
'cdn_js' => [
'https://cdn.example.com/swiper.min.js',
],
]css/js — скомпилированные ассеты страницы, генерируются командой cms:compile-assets из стилей блоков. cdn_* — внешние библиотеки, привязанные к используемым на странице блокам.
Минимальный шаблон
Реальный stub из пакета CMS:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<x-cms::meta-tags :page="$page" />
@foreach ($assets['cdn_css'] ?? [] as $css)
<link rel="stylesheet" href="{{ $css }}">
@endforeach
@if (!empty($assets['css']))
<link rel="stylesheet" href="{{ $assets['css'] }}">
@endif
</head>
<body>
@yield('blocks')
@foreach ($assets['cdn_js'] ?? [] as $js)
<script src="{{ $js }}"></script>
@endforeach
@if (!empty($assets['js']))
<script src="{{ $assets['js'] }}"></script>
@endif
</body>
</html>Ключевая строка — @yield('blocks'). Это место, куда page-wrapper вставит готовый HTML блоков. Использовать другие имена секций (content, main) нельзя — CMS жёстко прописана на blocks.
Встроенные компоненты в шаблоне
В Blade-шаблоне доступны все встроенные <x-cms::*> компоненты пакета. Часто используемые:
| Компонент | Назначение |
|---|---|
<x-cms::meta-tags :page="$page" /> | Полный набор meta-тегов: title, description, OG, Twitter, canonical, hreflang |
<x-cms::schema-org :page="$page" /> | JSON-LD Schema.org разметка |
<x-cms::breadcrumbs :items="$breadcrumbs" /> | Хлебные крошки |
<x-cms::pagination :paginator="..." /> | Пагинация |
<x-cms::share-buttons :url="..." /> | Кнопки поделиться в соцсетях |
Полный список — Компоненты и библиотеки.
Поля шаблона
Шаблон может иметь собственные поля — например, цвет header'а, флаг показа footer, ссылку на лого. Поля настраиваются в админке через UI шаблона и сохраняются в той же иерархии Tab → Section → Field, что и у блоков (через polymorphic fieldable_type = TemplatePage::class).
Значения этих полей доступны:
- Через атрибуты страницы (
$pageмодель), если поля попали в Page Type. - Через
$global(если шаблон выводит общие настройки сайта).
Подробнее о том, как поля шаблона связываются с типами страниц — Страницы.
Библиотеки шаблона
К шаблону можно привязать внешние JS/CSS-библиотеки через таблицу template_page_library. Когда страница использует шаблон, эти библиотеки попадают в $assets['cdn_css'] / $assets['cdn_js'] — и подключаются в HTML стандартным @foreach.
Создание шаблона
Через UI
- Меню Шаблоны → Создать.
- Указать slug, имя.
- Написать Blade-код в встроенном редакторе кода (CodeMirror).
- Опционально — добавить SCSS и JS.
- Опционально — определить поля шаблона (для параметризации).
- Сохранить.
Код попадает в storage/cms/templates/<slug>/.
Через файловую систему
Можно сразу положить файлы в storage/cms/templates/<slug>/template.blade.php, но запись в template_pages всё равно нужна — чтобы страница могла на неё ссылаться. Создать запись — через UI «Шаблоны» или REST API.
Команды cms:make-template нет — шаблоны создаются только через UI или импорт ZIP.
Импорт и экспорт
Шаблоны экспортируются в ZIP через раздел «Экспорт/Импорт». Архив содержит:
- JSON-описание: метаданные шаблона, иерархия табов/секций/полей, привязанные библиотеки, screenshot.
- Файлы:
template.blade.php,style.scss,script.js.
При импорте TemplatePage::fromImportArray() создаёт запись и связанные сущности по слагам.
Подводные камни
Подводные камни
- Шаблон — это полный HTML-документ с
<!DOCTYPE>,<html>,<head>,<body>, а не фрагмент. CMS не оборачивает его дополнительно —page-wrapperтолько расширяет шаблон и подставляет блоки в секцию. - Имя секции для блоков — только
blocks(@yield('blocks')). Другие имена работать не будут, потому чтоpage-wrapperжёстко прописан. - Все шаблоны живут в
storage/cms/templates/. Альтернативного app/-источника нет. - Для head-блока используйте
<x-cms::meta-tags :page="$page" />вместо ручных<title>/<meta>— компонент учитывает SEO-настройки страницы, OG-теги, hreflang. - SCSS шаблона компилируется через
scssphp(PHP-реализация Sass). После правки SCSS —cms:compile-assetsилиcms:cache-clear. - Шаблоны редактируются через UI как обычный код. Прямая правка файлов в IDE подхватывается (Laravel не кэширует view, если
APP_DEBUG=true), но в production не забудьтеphp artisan view:clear.
Связанные разделы
- Страницы — как страница привязывается к шаблону
- Блоки — что вставляется в
@yield('blocks') - Поля — типы полей шаблона
- Компоненты и библиотеки — встроенные
<x-cms::*>и внешние библиотеки - Файлы и медиа —
<x-cms::image>