Flex-объекты¶
Эндпоинты для управления директориями Flex-объектов и их записями: вывод директорий и схем, полный CRUD для объектов, экспорт в YAML и медиафайлы отдельного объекта (файлы, хранящиеся рядом с объектом в его собственной папке).
Получение конфигурации Flex¶
GET /flex-objects/config
Возвращает конфигурацию плагина Flex Objects, значимую для интерфейса (никогда не секреты). Используется админкой для начальной загрузки интерфейса Flex Objects.
Ответ
{"data": {"enabled": true, "built_in_css": true, "security": {"restrict_page_frontmatter": true}, "admin_list": {"per_page": 15, "order": {"by": "updated_timestamp", "dir": "desc"}}}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения api.access. |
Облегчённый эндпоинт конфигурации. Список директорий возвращается отдельно через GET /flex-objects, чтобы вызывающие стороны, которым нужна только конфигурация, получали компактный ответ.
Список директорий¶
GET /flex-objects
Выводит включённые пользовательские директории Flex, которые текущему пользователю разрешено просматривать, с их конфигурацией списка и редактирования в админке, настройками поиска и разрешёнными типами полей столбцов списка. Встроенные директории, для которых уже есть отдельный интерфейс в админке (pages, user-accounts, user-groups), исключаются.
Ответ
{"data": [{"type": "contacts", "title": "Contacts", "description": "Address book", "icon": "fa-address-book", "list": {"fields": {"name": {}, "email": {}}}, "edit": {}, "search": {"fields": ["name", "email"]}, "field_types": {"name": "text", "email": "email"}, "field_options": {}, "export": {}}]}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения api.access. |
Поле type каждой записи — ключ директории Flex, который вы передаёте как {type} эндпоинтам объектов ниже. Директории, на которые у пользователя нет разрешения list, в результат не попадают, как и директории, чья схема не имеет раздела admin или задаёт admin.disabled. Каждая запись содержит те же поля, что и Метаданные директории.
Список схем¶
GET /flex-objects/blueprints
Выводит все доступные схемы директорий Flex, включая скрытые и выключенные в данный момент. Используется для выбора директории на странице настроек плагина.
Ответ
{"data": [{"url": "blueprints://flex-objects/contacts.yaml", "legacy_url": null, "type": "contacts", "title": "Contacts", "description": "Address book"}]}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения api.access. |
legacy_url содержит ранее существовавший псевдоним схемы (если он есть), чтобы можно было сопоставить сохранённые настройки, которые всё ещё ссылаются на старую форму.
Список объектов¶
GET /flex-objects/{type}
Выводит объекты директории Flex с поиском, сортировкой и постраничной разбивкой. Каждый элемент сокращён до настроенных полей списка директории (плюс key).
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
page |
integer | Нет | Номер страницы для постраничной разбивки (по умолчанию 1). |
per_page |
integer | Нет | Число результатов на странице. По умолчанию admin.list.options.per_page директории, иначе значение API по умолчанию (20); максимум 1000. |
search |
string | Нет | Поисковый запрос, применяемый к полям директории, доступным для поиска. |
filters |
object | Нет | Точные фильтры по полям в виде параметров запроса filters[field]=value или строки JSON-объекта. Значение-массив совпадает с любым из своих значений; key или id совпадает с ключом объекта. |
sort |
string | Нет | Поле для сортировки. По умолчанию admin.list.options.order.by директории, иначе без сортировки. |
order |
string | Нет | Направление сортировки: asc или desc. По умолчанию настроенное направление директории, иначе asc. |
Ответ
{"data": [{"key": "ada", "name": "Ada Lovelace", "email": "ada@example.com"}], "meta": {"pagination": {"page": 1, "per_page": 20, "total": 1, "total_pages": 1}}, "links": {"self": "https://example.com/api/v1/flex-objects/contacts?page=1&per_page=20"}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения list директории. |
404 |
Тип директории не найден или не включён. |
key каждого элемента — идентификатор объекта, который вы передаёте как {key} эндпоинтам отдельного объекта. Директория без настроенных полей списка возвращает вместо этого полные данные каждого объекта. Когда директория настраивает связанный список подробностей (admin.list.detail), видимый пользователю, каждый элемент также несёт объект __detail с описанием связанной директории, фильтра, выбирающего его записи, и того, может ли пользователь их редактировать или удалять.
Получение объекта¶
GET /flex-objects/{type}/{key}
Возвращает один объект по ключу с его полными сериализованными данными. Ответ содержит ETag, который можно использовать для оптимистичного контроля параллелизма при обновлении.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
key |
string | Да | Ключ объекта. |
Ответ
{"data": {"key": "ada", "__meta": {"type": "contacts", "key": "ada", "storageKey": "ada", "storagePath": "user-data://flex-objects/contacts/ada"}, "name": "Ada Lovelace", "email": "ada@example.com"}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения read директории. |
404 |
Директория или объект не найдены. |
Сохраните полученный ETag и отправьте его обратно в заголовке If-Match при обновлении, чтобы параллельное изменение было обнаружено, а не молча перезаписано.
Зарезервированный объект __meta — доступная только для чтения информация для админки (тип объекта, ключ, ключ хранения и, когда известно, папка хранения). Он никогда не сохраняется: создание и обновление удаляют его из тела запроса.
Создание объекта¶
POST /flex-objects/{type}
Создаёт новый объект в директории Flex. Тело запроса содержит значения полей объекта. Новый ключ назначается хранилищем директории и возвращается в ответе и заголовке Location.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
Запрос
Ответ
{"data": {"key": "grace-hopper", "__meta": {"type": "contacts", "key": "grace-hopper", "storageKey": "grace-hopper"}, "name": "Grace Hopper", "email": "grace@example.com"}}
Коды ответов
| Код | Описание |
|---|---|
201 |
Объект создан. Заголовок Location указывает на новый объект. |
401 |
Не авторизован. |
403 |
Нет разрешения create директории, либо директория — это user-accounts или user-groups, которые нужно изменять через эндпоинты пользователей и групп. |
404 |
Тип директории не найден или не включён. |
422 |
Ошибка валидации (объект не удалось создать из переданных данных). |
Отправляйте POST на адрес коллекции (без сегмента ключа). Чтобы затем прикрепить файлы к объекту, используйте эндпоинт Загрузка медиафайлов объекта ниже с ключом, возвращённым здесь.
Обновление объекта¶
PATCH /flex-objects/{type}/{key}
Обновляет существующий объект. Тело запроса содержит только изменяемые поля (частичное слияние). При необходимости отправьте заголовок If-Match с ETag из предыдущего получения, чтобы защититься от параллельных правок.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
key |
string | Да | Ключ объекта. |
Запрос
Ответ
{"data": {"key": "grace-hopper", "__meta": {"type": "contacts", "key": "grace-hopper", "storageKey": "grace-hopper"}, "name": "Grace Hopper", "email": "grace.hopper@example.com"}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Объект обновлён. Ответ содержит новый ETag. |
401 |
Не авторизован. |
403 |
Нет разрешения update директории, либо директория — это user-accounts или user-groups, которые нужно изменять через эндпоинты пользователей и групп. |
404 |
Директория или объект не найдены. |
409 |
Переданный If-Match ETag устарел; объект изменился после того, как вы его получили. |
422 |
Ошибка валидации. |
Это частичное обновление: пропущенные поля остаются нетронутыми. Используйте PATCH, а не POST (POST на URL объекта не разрешён).
Если тело отправляет поле файла (file, avatar, pagemedia или любое поле с destination) без файла, который оно содержало ранее, этот файл удаляется из собственной папки объекта при сохранении объекта. Файлы в общем месте назначения, например media://, лишь отвязываются от поля и остаются на диске.
Удаление объекта¶
DELETE /flex-objects/{type}/{key}
Удаляет объект из директории Flex. Для директорий на основе папок это также удаляет папку объекта вместе со всеми прикреплёнными медиафайлами.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
key |
string | Да | Ключ объекта. |
Коды ответов
| Код | Описание |
|---|---|
204 |
Объект удалён. |
401 |
Не авторизован. |
403 |
Нет разрешения delete директории, либо директория — это user-accounts или user-groups, которые нужно изменять через эндпоинты пользователей и групп. |
404 |
Директория или объект не найдены. |
При успехе тело ответа пустое.
Экспорт директории¶
GET /flex-objects/{type}/export
Экспортирует все объекты директории в один YAML-документ, возвращаемый как скачиваемый файл (с ключами объектов).
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
Коды ответов
| Код | Описание |
|---|---|
200 |
Скачивание YAML-файла (Content-Disposition: attachment). |
401 |
Не авторизован. |
403 |
Нет разрешения read директории. |
404 |
Тип директории не найден или не включён, либо экспорт для директории не включён. |
Экспорт работает только для директорий, чья схема задаёт admin.export.enabled; встроенные директории учётных записей, групп и страниц этого не делают и возвращают 404. Поскольку он возвращает все поля всех объектов, требуется разрешение read директории, а не только list.
Ответ имеет тип application/x-yaml и имя файла вида contacts-YYYY-MM-DD.yaml, а не стандартную JSON-обёртку.
Список медиафайлов объекта¶
GET /flex-objects/{type}/{key}/media
Выводит медиафайлы, прикреплённые к одному объекту. Для директорий на основе папок они лежат в собственной папке хранения объекта, рядом с его файлом данных.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
key |
string | Да | Ключ объекта. |
Ответ
{"data": [{"filename": "avatar.png", "type": "image/png", "size": 20480, "url": "/user/data/flex-objects/contacts/ada/avatar.png"}]}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения read директории. |
404 |
Директория или объект не найдены. |
422 |
У директории нет папки медиафайлов для отдельных объектов (она использует хранение в одном файле). |
Медиафайлы объектов требуют хранения на основе папок (одна папка на объект, например user-data://flex-objects/contacts/{id}). Директории, которые хранят все записи в одном общем файле, не имеют места для файлов отдельных объектов, и эндпоинт возвращает 422.
Загрузка медиафайлов объекта¶
POST /flex-objects/{type}/{key}/media
Загружает один или несколько файлов в объект. Для директорий на основе папок файлы сохраняются в собственной папке объекта, рядом с его файлом данных.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
key |
string | Да | Ключ объекта. |
file |
file | Да | Файл(ы) для загрузки (multipart/form-data). Поддерживаются вложенные поля вида file[]. |
Ответ
{"data": [{"filename": "avatar.png", "url": "/user/data/flex-objects/contacts/ada/avatar.png", "type": "image/png", "size": 20480}]}
Коды ответов
| Код | Описание |
|---|---|
201 |
Файл(ы) загружены; ответ перечисляет текущие медиафайлы объекта. |
401 |
Не авторизован. |
403 |
Нет разрешения update директории. |
404 |
Директория или объект не найдены. |
422 |
Файл не передан, недопустимый тип или размер файла, либо директория без папок медиафайлов для отдельных объектов (хранение в одном файле). |
Отправляйте файл как запрос multipart/form-data (установите Content-Type: multipart/form-data), а не JSON. Загрузки проверяются по списку опасных расширений Grav и ограничению размера в 64 МБ. Требуется хранение директории в виде папок (одна папка на объект); директории с хранением в одном файле возвращают 422.
Поле файла может передавать собственные настройки загрузки как дополнительные поля формы: random_name, avoid_overwriting, accept и filesize (в МБ). Они только ужесточают проверки выше; поднять ограничение в 64 МБ они не могут.
Удаление медиафайла объекта¶
DELETE /flex-objects/{type}/{key}/media/{filename}
Удаляет один медиафайл из папки объекта (вместе с сопутствующим файлом .meta.yaml).
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Тип директории Flex (например, contacts). |
key |
string | Да | Ключ объекта. |
filename |
string | Да | Имя удаляемого медиафайла. |
Коды ответов
| Код | Описание |
|---|---|
204 |
Файл удалён. |
401 |
Не авторизован. |
403 |
Нет разрешения update директории. |
404 |
Директория, объект или файл не найдены. |
422 |
Неверное имя файла (скрытый файл или файл с ..), либо у директории нет папки медиафайлов для отдельных объектов (хранение в одном файле). |
При успехе тело ответа пустое.
Метаданные директории¶
GET /flex-objects/{type}/metadata
Возвращает метаданные Admin Next одной директории (конфигурацию списка и редактирования, настройки поиска, разрешённые типы полей столбцов списка и метки параметров). В отличие от раздела «Список директорий», этот эндпоинт обслуживает и встроенные директории, такие как user-accounts, поэтому отдельная страница Admin Next может повторно использовать конфигурацию списка и подробностей Flex, не добавляя дублирующую запись в боковую панель.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Ключ директории Flex. |
Ответ
{"data": {"type": "contacts", "title": "Contacts", "description": "Address book", "icon": "fa-address-book", "list": {"fields": {"name": {}, "email": {}}}, "edit": {}, "search": {"fields": ["name", "email"]}, "field_types": {"name": "text", "email": "email"}, "field_options": {}, "export": {}}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения api.access или у пользователя нет разрешения list на директорию. |
404 |
Директория не найдена или не включена. |
Это те же данные, что несёт каждая запись Списка директорий, полученные для одной директории. field_types и field_options позволяют клиенту рендерить типизированные ячейки списка (даты как даты, значения выбора как их метки) вместо необработанных сохранённых значений.
Получение схемы¶
GET /blueprints/flex-objects/{type}
Возвращает сериализованную схему формы директории Flex, готовую к рендерингу формы создания и редактирования клиентом. Метки разрешаются на язык админки вошедшего пользователя, а событие onApiBlueprintResolved вызывается, чтобы плагины могли скорректировать список полей.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type |
string | Да | Ключ директории Flex. |
Ответ
{"data": {"name": "contacts", "title": "Contacts", "type": null, "child_type": null, "validation": "loose", "fields": [{"name": "name", "type": "text", "label": "Name"}, {"name": "email", "type": "email", "label": "Email"}]}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Успех. |
401 |
Не авторизован. |
403 |
Нет разрешения api.access. |
404 |
Директория не найдена или не включена. |
Это определение формы (поля, типы, метки, валидация), а не данные объекта. Именно его запрашивает Admin Next, чтобы построить редактор объекта Flex. Для значений записи используйте Получение объекта.