Skip to content

Блоки

Блок — переиспользуемая единица контента: hero-баннер, преимущества, форма обратной связи, галерея. Страница собирается из блоков в конструкторе или через API.

Структура блока

Блок описывается в двух местах:

ГдеЧто хранится
БД (таблица blocks и связанные)Метаданные (slug, name, тип), поля, табы, секции, пресеты, связи с actions и библиотеками
Файловая система (storage/cms/blocks/<slug>/)Код: template.blade.php, style.scss, script.js

Колонки таблицы blocks

ПолеНазначение
slugУникальный идентификатор (hero-banner, латиница нижнего регистра через дефис)
nameОтображаемое название
descriptionОписание
block_type_idFK на block_types (см. ниже)
sourcedatabase / file / vendor — где живёт код блока
pathПуть к коду (для source = file)
controllerКастомный PHP-контроллер (опционально)
tagsТеги для группировки в админке
screenFK на files (скриншот блока для UI)
orderПорядок в списке
no_wrapperBoolean — отключить автоматическую обёртку рендера

Связанные таблицы

ТаблицаСодержит
block_fieldsПоля блока (см. Поля)
block_tabsВкладки админ-формы блока
block_sectionsСекции внутри табов
block_actionsПривязки actions к блоку с параметрами
block_libraryPivot блок ↔ библиотека (внешние JS/CSS)
block_presetsПресеты значений полей
page_blocksРазмещение блока на странице
city_page_blocksCity-вариант размещения

Файлы на диске

В директории storage/cms/blocks/<slug>/ обычно лежат:

storage/cms/blocks/hero-banner/
├── template.blade.php    — Blade-шаблон рендера (обязательно)
├── style.scss            — стили блока (опционально)
└── script.js             — JS-логика (опционально)

Типы блоков

Сидеры CMS создают четыре системных типа:

block_type_idТип
1Контент
2Медиа
3Навигация
4Формы

Дополнительные типы создаются через UI «Типы блоков» или MCP-tool create_block_type. Тип используется для фильтрации в админке и группировки; логика рендера от типа не зависит.


Источники кода блока

Поле source в таблице blocks указывает, откуда брать файлы блока. BlockRegistry поддерживает три источника:

sourceГде ищется кодКто туда пишет
databasestorage/cms/blocks/<slug>/Сама CMS (правка через редактор кода в админке)
fileapp/Blocks/<slug>/ или произвольный path из БДРазработчик вручную
vendorРегистрация через ServiceProvider пакетаПоставлено CMS-пакетом или модулем

BlockRegistry::find() возвращает реализацию с высшим приоритетом источника: app > storage > vendor. Если в app/Blocks/<slug>/ лежит блок с тем же слагом — он перекроет storage и vendor.

TIP

Для блоков, которые должны попадать в Git, кладите файлы в app/Blocks/<slug>/ и установите source = file в записи блока. Для блоков, которые правят контент-менеджеры в админке, оставляйте source = database (тогда CMS сама пишет в storage/cms/blocks/).


Рендеринг блока

Рендером занимается Templite\Cms\Services\BlockRenderer. Алгоритм:

  1. Находит путь к блоку через BlockRegistry::find($block->slug).
  2. Читает template.blade.php из этой директории.
  3. Валидирует шаблон через BladeSecurityValidator — запрещённые конструкции (прямой доступ к файловой системе, опасные функции и т.п.) приводят к отказу в рендере и записи в security-log.
  4. Рендерит Blade с пятью переменными.
  5. Оборачивает результат в <div>, если у блока не выставлен no_wrapper.

Переменные в шаблоне

ПеременнаяСодержимое
$fieldsЗначения полей блока, обёрнутые в FieldsBag
$actionsПривязанные actions блока
$pageEloquent-модель текущей страницы
$globalЗначения глобальных настроек
$blockEloquent-модель самого блока

FieldsBag — обёртка над массивом полей. Для несуществующего ключа возвращает не null, а пустой FieldsBag. Это значит, что @foreach ($fields['missing'] as $item) пройдёт 0 итераций вместо ошибки.

Минимальный шаблон блока:

blade
<section>
    <h2>{{ $fields['title'] }}</h2>
    <p>{{ $fields['description'] }}</p>
</section>

Автоматическая обёртка

По умолчанию рендер каждого блока оборачивается в <div> с классами и data-атрибутами:

html
<div class="cms-block cms-block--hero-banner" data-block="hero-banner" data-block-id="hero-banner-65a3f...">
    ... содержимое блока ...
</div>

Это нужно для live-preview (сопоставление DOM-элемента с блоком в админке) и для целевого CSS. Если обёртка мешает — поставьте no_wrapper = true в записи блока.


Размещение блока на странице

Связь блок ↔ страница хранится в таблице page_blocks. Колонки:

ПолеНазначение
page_id, block_idFK
orderПорядок на странице
statusОпубликован / скрыт / черновик
cache_enabledBoolean — кэшировать рендер этого экземпляра (по умолчанию true)
page_block_data_idFK на page_block_data с конкретными значениями полей
Поля пресетаПривязанный пресет (опционально)

Для городских вариантов используется отдельная таблица city_page_blocks с теми же полями.


Пресеты блоков

Пресет — готовый набор значений полей блока. Например, «Hero — синий» и «Hero — тёмный с видео» для одного и того же блока hero-banner.

При добавлении блока на страницу можно выбрать пресет — его значения подставляются в новый экземпляр. После этого значения можно править индивидуально, не затрагивая сам пресет.

Управление пресетами:

  • UI: меню Пресеты блоков, или вкладка «Пресеты» внутри страницы блока.
  • MCP: tools list_presets, create_preset, update_preset, delete_preset.

Хранение: таблица block_presets (метаданные) + block_preset_data (значения полей пресета).


Кэширование рендера

Кэширование результата рендера каждого экземпляра блока на странице управляется флагом cache_enabled в page_blocks (по умолчанию true). Кэш инвалидируется при сохранении блока, страницы или связанных глобальных настроек.

Очистка вручную:

bash
docker exec templite-app php artisan cms:cache-clear

Пересборка скомпилированных ассетов страницы (CSS/JS из блоков):

bash
docker exec templite-app php artisan cms:compile-assets

Библиотеки и actions

К блоку можно привязать:

  • Внешние библиотеки (Swiper, AOS) через pivot-таблицу block_library. См. Компоненты и библиотеки.
  • Actions (PHP-классы для обработки событий — отправка формы, click-handler) через block_actions. Каждая привязка хранит JSON-параметры. См. Actions.

Импорт и экспорт

Блоки экспортируются в ZIP-архив через раздел Экспорт/Импорт в админке. Архив содержит:

  • JSON-описание блока: метаданные, иерархия табов → секций → полей, привязанные actions и библиотеки, screenshot.
  • Файлы кода блока: template.blade.php, style.scss, script.js (если есть).

При импорте Block::fromImportArray() восстанавливает запись и связанные сущности по слагам (block_type, actions, libraries — резолвятся через ImportContext). Файлы кода кладутся обратно в storage/cms/blocks/<slug>/.


Подводные камни

Подводные камни

  • Slug блока — латиница нижнего регистра через дефис (hero-banner). Имена файлов в storage/cms/blocks/ нормализуются через basename($slug) (без слешей, безопасно).
  • Файлы блока живут в storage/cms/blocks/<slug>/ — это часть storage/, не app/. Обязательно включайте папку в бэкап.
  • Правка файлов блока в IDE снаружи CMS подхватывается автоматически, но шаблон проходит через BladeSecurityValidator при каждом рендере. Если ваш шаблон содержит конструкции, которые CMS считает небезопасными, рендер вернёт HTML-комментарий вместо содержимого, а нарушение залогируется.
  • SCSS блока компилируется через scssphp (PHP-реализация Sass). Не все возможности Dart Sass поддерживаются — избегайте @use ... with с keyword arguments и сложных мета-функций. После правки SCSS — cms:compile-assets или cms:cache-clear.
  • Иерархия полей (вкладки → секции → поля) хранится в БД через polymorphic-связь (fieldable_type / fieldable_id), потому что та же иерархия используется для шаблонов страниц, типов страниц и других сущностей.

Связанные разделы

Распространяется под лицензией MIT.