Тема
Blueprint: Контентные страницы (Pages)
Когда применять
Страницы, которые контент-менеджер создаёт/правит в админке: «О компании», «Доставка», «Гарантии», лендинги услуг без собственной модели.
Не применять для: страниц с собственной сущностью (услуга, товар, статья — у них свои модели и blueprint'ы), главной (обычно отдельный контроллер с виджетами).
Состав решения
- Модель
Page+ миграция + фабрика - Контроллер
PageController@show(route model binding по slug) - Filament-ресурс
PageResource - Blade
pages/show.blade.phpна общем layout - Feature-тест
PageTest+ запись в sitemap-генерацию
Схема данных
| Столбец | Тип | Индекс | Cast / примечание |
|---|---|---|---|
| id | id | PK | |
| title | string | H1 страницы | |
| slug | string | unique | kebab-case, [a-z0-9-] |
| content | longText nullable | HTML из RichEditor | |
| blocks | json nullable | cast array; если нужен блочный конструктор (Filament Builder) | |
| meta_title | string nullable | приоритет над шаблонным | |
| meta_description | string nullable | ||
| is_active | boolean default true | index | скрытие без удаления |
| published_at | timestamp nullable | отложенная публикация (если требуется ТЗ) | |
| timestamps |
Правила реализации
- Роут:
GET /{page:slug}последним в web.php (fallback-паттерн) либо с префиксом/info/{page:slug}— решить по ТЗ; коллизии со статичными роутами проверять тестом. - Binding — только
is_activeстраницы:resolveRouteBindingили explicit query в контроллере; неактивная → 404. - Вывод
content—{!! !!}допустим: HTML доверенный, из админки (по specs/blade). Пользовательского ввода в content нет. - SEO: title/description по приоритету «ручное поле → шаблон → default»; canonical, OG-теги в layout (specs/seo). Страницы — в sitemap (только активные).
- Кеш: страница кешируется тегом
pages;afterSaveресурса — flush тега. - Filament: RichEditor (или Builder при
blocks), slug авто из title сunique(ignoreRecord: true), секция SEO — collapsed. - Блочный конструктор (
blocks) вводить только если ТЗ требует разнотипные секции; для текстовых страниц достаточно RichEditor — не переусложнять.
Пакеты
Ничего специального. Медиа в контенте — стандартный аттачмент RichEditor или spatie/laravel-medialibrary при галереях.
Шаги
- Миграция + модель (+ scope
active). - Контроллер show + роут с
->name('page.show'). - Blade-шаблон на layout с
@section('title')/@section('description'). - Filament-ресурс с SEO-секцией и flush кеша.
- Sitemap: включить активные страницы.
- Тесты: активная → 200 + title/h1; неактивная → 404; несуществующий slug → 404.
Чеклист приёмки
- [ ] Неактивная страница недоступна и отсутствует в sitemap
- [ ] Slug уникален, меняется без дублей; смена slug опубликованной страницы → предупредить о 301
- [ ] Meta ручные приоритетнее автогенерации; canonical есть
- [ ] Правка в админке видна на сайте сразу (кеш-теги сброшены)
- [ ] Роут страницы не перекрывает статические роуты (тест)