Компоненты и библиотеки
Два независимых понятия:
- Компонент — переиспользуемый Blade-фрагмент с namespace
cms::. Вызывается как<x-cms::image>. - Библиотека — внешний JS/CSS-пакет (Swiper, AOS), который привязывается к блокам или шаблонам и подключается на страницах автоматически.
Компоненты
Встроенные компоненты
CMS поставляет 11 готовых компонентов в packages/templite/cms/resources/views/components/:
| Компонент | Файл | Назначение |
|---|---|---|
<x-cms::breadcrumbs> | breadcrumbs.blade.php | Хлебные крошки |
<x-cms::filters> | filters.blade.php | UI-фильтр для списков страниц |
<x-cms::honeypot> | honeypot.blade.php | Anti-spam поле для форм |
<x-cms::image> | image.blade.php | Изображение с <picture> + AVIF/WebP/fallback |
<x-cms::lead-form> | lead-form.blade.php | Готовая форма-лид с CSRF и honeypot |
<x-cms::meta-tags> | meta-tags.blade.php | Полный набор meta-тегов: title, description, OG, Twitter, canonical, hreflang |
<x-cms::page-card> | page-card.blade.php | Карточка-превью страницы |
<x-cms::pagination> | pagination.blade.php | Пагинация |
<x-cms::schema-org> | schema-org.blade.php | JSON-LD Schema.org разметка |
<x-cms::share-buttons> | share-buttons.blade.php | Кнопки «поделиться» в соцсетях |
<x-cms::tiptap> | tiptap.blade.php | Рендер контента из поля tiptap |
Эти компоненты доступны без дополнительной регистрации — namespace cms подключается ServiceProvider'ом пакета.
Пример: <x-cms::image>
Самый часто используемый компонент. Реальная сигнатура:
@props(['file', 'size' => null, 'class' => '', 'loading' => 'lazy'])Использование:
<x-cms::image :file="$fields['hero']" />
<x-cms::image :file="$fields['hero']" size="wide" class="hero-img" />
<x-cms::image :file="$fields['avatar']" size="thumb" loading="eager" />Что делает:
- Рендерит
<picture>с тремя<source>: AVIF → WebP → оригинал (если соответствующие форматы сгенерированы для файла). - Подставляет
width/heightиз$file->meta(предотвращает CLS). - Использует
$file->meta['dominant_color']какbackgroundплейсхолдера. - Подставляет
altиз$file->altиtitleиз$file->title. loading="lazy"по умолчанию (через атрибут<img loading>).
Если $file пустой — компонент ничего не рендерит (нет @else блока).
Структура кастомных компонентов
В БД компоненты регистрируются записью в components:
| Колонка | Назначение |
|---|---|
slug | Уникальный идентификатор |
name | Отображаемое название |
source | database / file / vendor |
params | JSON-описание принимаемых props |
description | Описание для UI |
Код хранится в storage/cms/components/<slug>/:
storage/cms/components/price-tag/
├── index.blade.php — Blade-разметка (обязательно)
├── style.scss — стили (опционально)
└── script.js — JS-логика (опционально)Имя файла шаблона — index.blade.php, не component.blade.php и не <slug>.blade.php.
Источники (ComponentRegistry)
ComponentRegistry имеет три приоритета: app > storage > vendor.
| Источник | Путь | Формат |
|---|---|---|
app | app/View/Components/Cms/<Name>.php | PHP-класс (стандартный Laravel-компонент) |
storage | storage/cms/components/<slug>/index.blade.php | Anonymous Blade-компонент |
vendor | packages/templite/cms/resources/views/components/*.blade.php | Anonymous Blade-компонент |
Создание собственного компонента
Через UI
- Меню Компоненты → Создать.
- Указать slug, имя, описание.
- Описать
params(props компонента). - Написать Blade-код в редакторе.
- Опционально — SCSS и JS.
Файлы попадают в storage/cms/components/<slug>/.
Через файловую систему
Положить app/View/Components/Cms/<Name>.php (PHP-класс) или storage/cms/components/<slug>/index.blade.php (anonymous Blade). После этого <x-cms::name> или <x-cms::slug> будет работать.
Команда cms:make-component
Команда cms:make-component <Name> создаёт файлы в app/Cms/Components/<Name>/ — этот путь не сканируется ComponentRegistry. С флагом --storage команда правильно кладёт в storage/cms/components/<slug>/. Используйте --storage или переносите файлы вручную в app/View/Components/Cms/.
Импорт и экспорт
Компоненты экспортируются в ZIP через раздел «Экспорт/Импорт». Архив содержит:
- JSON-описание (slug, name, params, description)
- Файлы кода:
index.blade.php,style.scss,script.js
При импорте Component::fromImportArray() создаёт запись, importCodeFromZip() восстанавливает файлы в storage/cms/components/<slug>/.
Библиотеки
Библиотека — это внешний JS/CSS-пакет, подключаемый к публичной части сайта. Используется для drop-in решений типа Swiper, AOS, GLightbox.
Структура Library
| Колонка | Назначение |
|---|---|
slug | Уникальный идентификатор |
name | Отображаемое название |
version | Версия библиотеки |
description | Описание |
js_file | Путь к локальному JS (опционально, относительно storage/public) |
css_file | Путь к локальному CSS (опционально) |
js_cdn | URL JS на CDN (опционально) |
css_cdn | URL CSS на CDN (опционально) |
load_strategy | Стратегия загрузки JS: defer, async, обычная |
sort_order | Порядок подключения |
active | Boolean — включена ли библиотека |
Библиотека может иметь либо локальные файлы, либо CDN-ссылки, либо и то, и другое (CDN с локальным fallback).
Привязка к блоку и шаблону
| Pivot | Назначение |
|---|---|
block_library | Блок ↔ библиотеки |
template_page_library | Шаблон ↔ библиотеки |
При рендере страницы PageRenderer собирает все библиотеки, нужные блокам и шаблону этой страницы, и подключает их через переменную $assets:
$assets['cdn_css']— массив CSS-ссылок (CDN или локальных)$assets['cdn_js']— массив JS-ссылок
В шаблоне (storage/cms/templates/<slug>/template.blade.php) они выводятся так:
@foreach ($assets['cdn_css'] ?? [] as $css)
<link rel="stylesheet" href="{{ $css }}">
@endforeach
@foreach ($assets['cdn_js'] ?? [] as $js)
<script src="{{ $js }}"></script>
@endforeachСоздание библиотеки
Через UI:
- Меню Библиотеки → Создать.
- Указать slug, имя, версию.
- Заполнить либо CDN-ссылки (
js_cdn,css_cdn), либо загрузить локальные файлы. - Задать
load_strategy(обычноdeferдля JS). - Поставить
active = true.
После создания — открыть блок или шаблон, добавить связь с библиотекой.
Источник
В отличие от блоков и компонентов, у библиотек нет файлового кода в storage/cms/ в смысле app/storage/vendor. Локальные файлы (js_file, css_file) хранятся в storage/cms/libraries/<slug>/ после импорта/загрузки.
Подводные камни
Подводные камни
- Имя файла кастомного компонента —
index.blade.php. Другие имена (<slug>.blade.php,component.blade.php)ComponentRegistryне найдёт. cms:make-componentбез--storageсоздаётapp/Cms/Components/<Name>/— runtime туда не смотрит. Используйте--storageили кладите вручную вapp/View/Components/Cms/<Name>.php(PHP-класс).- Slug компонента в
<x-cms::slug>— kebab-case. Если в БДslug = "price-tag", вызывается как<x-cms::price-tag>. - Встроенные компоненты (
<x-cms::image>и др.) переопределить черезapp/можно: положитьapp/View/Components/Cms/Image.php— он перекроет vendor-версию (app>vendor). - Библиотека подключается на страницу только если хотя бы один блок или шаблон страницы ссылается на неё. Лишние библиотеки в HTML не попадут.
load_strategy = "defer"подходит большинству библиотек."async"— для аналитики и других независимых скриптов. Если библиотека влияет на DOM сразу — оставьтеnull(sync-загрузка).- Локальные файлы библиотеки (
js_file,css_file) хранятся как пути относительноstorage/app/public/(diskpublic). URL получается черезStorage::url($path).
Связанные разделы
- Блоки — где компоненты вызываются и куда библиотеки привязываются
- Шаблоны — подключение в layout через
$assets - Поля —
<x-cms::image>,<x-cms::tiptap>для рендера полей - Файлы и медиа — модель
File, форматы AVIF/WebP - Концепции — Принцип трёх источников