# Модуль: Блог

[← К оглавлению](../README.md)

Раздел статей с публикацией из админки, транслит-slug и микроразметкой schema.org.

## Публичная часть

- `GET /blog` — список опубликованных статей (`BlogController@index`, пагинация по 12, карточки с обложкой).
- `GET /blog/{article}` — статья (`BlogController@show`, биндинг по `slug`). Неопубликованные → 404.
- Ссылка **«Блог»** — в подвале (`resources/views/partials/footer.blade.php`).
- Вьюхи: `resources/views/blog/index.blade.php`, `blog/show.blade.php` (стиль контента — класс `.page-content`, как у статических страниц).

## Модель `App\Models\Article`

Таблица `articles`: `slug` (unique), `title`, `excerpt`, `content` (HTML), `cover_path` (обложка на public-диске), `author_name`, `is_published`, `published_at`.

- **Slug — транслит из заголовка**: `Article::uniqueSlug()` через `Str::slug()` (кириллица → латиница), уникальность через суффикс `-2`, `-3`. Генерируется в хуке `saving`, если поле пустое; редактируется вручную в форме.
- `published_at` авто-проставляется при первой публикации.
- `scopePublished()` — `is_published = true` и `published_at <= now` (либо null), свежие первыми.
- Хелперы: `coverUrl()` (обложка или `seo.default_image`), `authorName()` (fallback — название сайта), `summary()` (excerpt или начало контента, для списка и meta).

## Админка

`app/Filament/Resources/Articles/` — раздел **Контент → «Блог»**:
- **Форма**: заголовок (авто-slug при создании), slug, обложка (`FileUpload`, public-диск), краткое описание, автор, дата публикации, тумблер «Опубликовано», `RichEditor` (вложения на public-диске).
- **Таблица**: превью обложки, заголовок + `/blog/<slug>`, статус, автор, даты; фильтр по публикации; на странице правки — действие **«Открыть на сайте»**.

## SEO / микроразметка

- `BlogController` наполняет `seo()`: title, description (`summary()`), canonical, og:image (обложка).
- **JSON-LD `BlogPosting`** — `App\Support\Schema::article()`: `headline`, `author`, `publisher`, `image`, `description`, `datePublished`, `dateModified`, `mainEntityOfPage`; плюс `BreadcrumbList`. Рендерится в `<head>` через `partials/seo.blade.php`.
- **Sitemap**: `SitemapController@blog` → `/sitemap-blog.xml` (страница блога + опубликованные статьи), включён в индекс `/sitemap.xml`.

> Формат JSON-LD рекомендован Google. Если для Яндекса потребуется Microdata — можно продублировать разметку атрибутами прямо в `blog/show.blade.php`. После правок проверяйте валидатором (Rich Results Test / Schema Markup Validator).

См. также: [admin.md](admin.md), [catalog.md](catalog.md) (общий SEO-механизм `seo()` и `Support/Schema`).
