Типы контента и поля
Как модуль объявляет свой тип записей с адресами, SEO и полями — и выводит их на витрине.
Тип контента объявляется в install() модуля — кодом, а не в базе руками. Так он одинаков на всех сайтах и обновляется вместе с модулем.
Тип
$contentTypes->upsert(
ContentType::define('event')
->label('События', 'Событие')
->icon('calendar')
->behaviors([
ContentTypeBehavior::Sluggable,
ContentTypeBehavior::Publishable,
ContentTypeBehavior::Seoable,
ContentTypeBehavior::Translatable,
])
->route('/events/{slug}')
->archive('/events', 'archive-event.twig')
->module('mymodule')
->build(),
);
Поведения: Sluggable (адрес), Publishable (статусы и даты), Revisionable (версии), Seoable (вкладка SEO), Translatable (языки), Sortable, Hierarchical (дерево), Blockable (раскладка из блоков).
Поля
$fieldGroups->save(
FieldGroup::define('event_content')
->title('Событие')
->location(fn ($l) => $l->where('content_type', '=', 'event'))
->fields([
Field::datetime('starts_at')->label('Начало')->required(),
Field::image('cover')->label('Обложка'),
Field::wysiwyg('body')->label('Описание')->translatable(),
Field::relation('venue')->label('Площадка')->to('venue'),
Field::repeater('program')->label('Программа')->fields([
Field::text('time')->label('Время'),
Field::text('title')->label('Что')->translatable(),
]),
]),
);
Типы полей: text, textarea, wysiwyg, number, price, switch, select, multiselect, date, datetime, image, gallery, file, relation, link, color, icon, repeater, group, json и др. Группа сохраняется по коду с сохранением id полей — данные записей не теряются при обновлении.
Витрина
Шаблоны записи и архива — в templates/ модуля: entry-event.twig, archive-event.twig. Тема может положить файл с тем же именем и переопределить вид.
{% extends 'base.twig' %}
{% block content %}
<h1>{{ entry.title }}</h1>
<p>{{ entry.field('starts_at')|date('d.m.Y H:i') }}</p>
{{ entry.field('body')|raw }}
{% endblock %}
Списки — cms_entries('event', 6), cms_query('event', {per_page: 12}), одна запись — cms_entry(id), адрес — entry_url(entry).