Как работает Flex¶
Прежде чем создавать свой первый тип Flex, полезно иметь ясную мысленную модель составных частей и того, как они соединяются. Flex состоит из нескольких небольших понятий, каждое из которых делает одну работу. Как только вы сможете их назвать, схемы, экраны Admin Next и REST API начнут складываться в понятную картину.
Эта страница проходит по каждой части, объясняет, как запрос превращается в загруженные объекты, и показывает три способа регистрации типа Flex в Grav.
Составные части¶
Flex — это две вещи, работающие вместе: основной фреймворк (Grav\Framework\Flex), который живёт в самом Grav, и плагин Flex Objects, который строит на нём фичи (регистрацию директорий, интерфейс Admin Next, REST API, шорткод [flex-objects], а также маршрутизацию страниц фронтенда и шаблоны). Фреймворк даёт объекты и хранилище; плагин даёт инструменты для управления ими.
Вот понятия, с которыми вы встретитесь, от контейнера до отдельной записи.
Flex¶
Flex — контейнер и реестр всех директорий сайта.
Это единая точка доступа ко всем вашим данным. После регистрации директории любая страница, плагин и тема могут добраться до её объектов через Flex. Grav поставляется со своими встроенными директориями (например, учётные записи пользователей и страницы), а плагины и темы могут регистрировать свои.
Примечание
Даже если версии Flex для учётных записей пользователей или страниц не включены для редактирования, вы всё равно можете читать их версии Flex и на фронтенде, и в Admin Next.
Тип Flex¶
Тип Flex — схема для директории.
Он определяет всё необходимое для хранения, отображения и редактирования данных: структуру данных, поля формы, права доступа, слой хранения и файлы шаблонов. Тип описывается одним YAML-файлом схемы. С его разделами (title, description, type, config, blueprints, form) вы познакомитесь на следующих страницах.
Директория Flex¶
Директория содержит все объекты одного типа.
Если тип — это форма для отливки, то директория — ящик, в котором хранится каждый объект, созданный по этой форме. Каждая директория владеет коллекцией объектов, опираясь на индекс для быстрых запросов и слой хранилища для чтения и записи файлов.
Flex-объект¶
Flex-объект — отдельная запись, один экземпляр типа.
Объект даёт доступ к своим свойствам и связанным данным, включая медиафайлы, когда хранилище это поддерживает. Объект знает, как отрендерить себя, какую форму использовать при редактировании и как сохранить или удалить себя. Если вы не определяете собственный класс, объекты используют по умолчанию Grav\Common\Flex\Types\Generic\GenericObject.
Коллекция Flex¶
Коллекция — набор объектов, к которому можно делать запросы.
Коллекция обычно содержит только объекты, нужные для текущей страницы или действия, а не всю директорию. Она даёт инструменты для фильтрации, сортировки, поиска, постраничного вывода и работы с набором, а также методы для рендеринга всей группы сразу. Класс по умолчанию — GenericCollection.
Индекс Flex¶
Индекс — лёгкий и быстрый поиск по директории.
Он хранит метаданные об объектах (ключи, временные метки, контрольные суммы), но не полные данные объектов. Grav использует индекс, чтобы быстро отвечать на операции списков и запросов, а полные объекты загружает из хранилища только тогда, когда они действительно нужны. Класс по умолчанию — GenericIndex.
Важно
Поскольку индекс играет центральную роль в том, что Flex остаётся быстрым, Flex не подходит для наборов данных, которые постоянно записываются или обновляются. Каждая запись обновляет индекс. Для нагрузок с высокой частотой записи лучше подойдёт настоящая база данных.
Хранилище Flex¶
Хранилище — слой, который читает и записывает данные объектов на диск.
Flex поставляется с тремя стратегиями, выбираемыми через config.data.storage:
| Стратегия | Что делает | Медиафайлы |
|---|---|---|
SimpleStorage |
Хранит каждый объект в одном общем файле. | Нет медиафайлов для отдельных объектов |
FileStorage |
Один файл на объект, все внутри одной папки. | Нет медиафайлов для отдельных объектов |
FolderStorage |
Одна папка на объект. | Поддерживает медиафайлы |
Хранилище также можно задать короткой однострочной формой (путь потока user-data:// к файлу .json), когда вам нужно простое расположение. Данные читаются и записываются через форматтер (Json, Yaml, Markdown, Serialize, Ini или Csv). Подробно хранилище настраивается на странице Схема.
Форма Flex¶
Форма создаёт и редактирует объект.
Flex интегрируется с плагином Form, поэтому те же типы полей, что вы используете в других местах Grav, работают и здесь. Тип может определять несколько представлений, позволяя разным формам редактировать разные части объекта. Admin Next использует эти формы для экранов создания и редактирования.
Как части соотносятся¶
┌───────────────────────────────────────────────┐
│ Flex │
│ (container / registry) │
│ │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ Directory │ │ Directory │ … │
│ │ (one Type) │ │ (one Type) │ │
│ └───────┬───────┘ └───────────────┘ │
└───────────┼───────────────────────────────────┘
│
┌───────────┴───────────────────────────────┐
│ │
┌────┴─────┐ ┌───────────┐ ┌─────────┐ ┌────┴─────┐
│ Index │ │Collection │ │ Form │ │ Storage │
│(metadata)│ │(a queried │ │(create/ │ │(files on │
│ │ │ set) │ │ edit) │ │ disk) │
└────┬─────┘ └─────┬─────┘ └─────────┘ └────┬─────┘
│ │ │
│ ┌────┴─────┐ │
└─────────▶│ Object │◀─────────────────────┘
│ (one │
│ record) │
└──────────┘
Читайте сверху вниз: Flex содержит много директорий. Каждая директория — это один тип, она управляет индексом, выдаёт коллекции, редактируется через форму и сохраняется через хранилище. И индекс, и хранилище в конечном счёте ведут к отдельным объектам.
Жизненный цикл объекта¶
Вы редко работаете с этим механизмом напрямую, но знание порядка событий объясняет, почему Flex ведёт себя именно так.
- Запрос. Страница, плагин, шорткод или REST-вызов запрашивает у директории объекты: полный список, отфильтрованную коллекцию или один объект по ключу.
- Сначала индекс. Flex отвечает из индекса. Вывод списка, поиск, сортировка и постраничный вывод работают с этими облегчёнными метаданными, поэтому список из тысячи записей никогда не загружает тысячу файлов.
- Загрузка из хранилища по требованию. Когда вы действительно читаете данные объекта (или рендерите его), Flex загружает этот объект из хранилища через его форматтер и наполняет им экземпляр объекта.
- Кэш. Загруженные объекты и данные индекса кэшируются, поэтому повторное обращение в рамках запроса (и между запросами, в зависимости от настроек кэша) не перечитывает диск. Сохранение или удаление объекта обновляет индекс и сбрасывает соответствующие записи кэша.
Вывод: дешёвые операции (подсчёт, вывод списка, фильтрация) остаются на индексе, а дорогая операция (чтение полных данных объекта) выполняется только когда она нужна.
Где что находится и как тип регистрируется¶
Тип Flex должен быть зарегистрирован в контейнере Flex, прежде чем Grav узнает о его существовании. Это происходит тремя способами.
1. Схема, которую вы включаете (обычный случай)¶
Поместите схему в:
Затем активируйте её в Admin Next в разделе Plugins > Flex Objects, в поле directories. Добавление там дописывает путь к схеме в конфигурацию плагина, и плагин Flex Objects регистрирует директорию при следующем запросе. Так появляются большинство типов данных для конкретного сайта (список контактов, каталог товаров, таблица событий). PHP не требуется.
Совет
<type> в имени файла становится ключом директории и появляется в пути REST API (/flex-objects/<type>) и при поиске шаблонов Twig (flex/<type>/...). Держите его в нижнем регистре и неизменным.
2. Плагин или тема, поставляющая схему¶
Плагин или тема может содержать собственную схему и регистрировать директорию из PHP, слушая событие FlexRegisterEvent. При запуске Flex вызывает это событие, чтобы расширения могли программно добавить свои типы в контейнер. Это правильный подход, когда вы распространяете тип в составе плагина или темы, потому что пользователю не нужно ничего включать вручную. Схема путешествует вместе с расширением, а не лежит в user/blueprints.
3. Встроенные типы ядра¶
Некоторые типы Grav регистрирует сам. Учётные записи пользователей и страницы — встроенные директории Flex, доступные даже когда их редактируемые версии Flex не включены. Их регистрировать не нужно; они часть фреймворка.
Предупреждение
Регистрация типа — не то же самое, что предоставление доступа к нему. Начиная с Flex Objects 1.4.3 (исправление безопасности GHSA-23vq-365v-qcmh) директория, схема которой не объявляет блок разрешений, закрыта для всех, кроме суперадминистраторов, по REST API. Прочитайте страницу Права доступа, прежде чем открывать тип редакторам.
Что дальше¶
- Определение типа Flex проходит по файлу схемы раздел за разделом.
- Права доступа объясняет префиксы
admin.<type>иapi.<type>и правило отказа по умолчанию. - REST API описывает все эндпоинты.
- Отображение Flex на фронтенде охватывает шорткод, тип страницы и шаблоны Twig.