Реестр источников
Реестр отвечает на два вопроса автора блока: какие данные вообще бывают и кто их поставляет. Это локальная копия каталога, который ведёт витрина; в PageCraft записи не создаются и не редактируются — они приходят синхронизацией.
Два уровня: тип результата и источник
Заголовок раздела «Два уровня: тип результата и источник»| Сущность | Идентификатор | Что описывает |
|---|---|---|
| Тип результата | product_list |
форму данных: что такое «список товаров» |
| Источник | catalog.products |
конкретного поставщика этих данных и его параметры |
Один тип результата — много источников. Товары рубрики, избранное и результаты
поиска возвращают одинаково устроенный product_list, поэтому один шаблон блока
работает со всеми тремя. Ровно это и позволяет перечислять их в allowedSources
одного слота: все источники слота обязаны иметь один result_type_id.
Поля источника
Заголовок раздела «Поля источника»| Поле | Что |
|---|---|
id |
строковый идентификатор; его кладут в allowedSources и default |
result_type_id |
какой тип результата источник отдаёт |
title, description |
человекочитаемые название и описание (могут отсутствовать) |
params_schema |
JSON Schema объекта params привязки |
context |
окружения, из которых источник берёт данные; пусто — работает везде |
synced_at |
когда запись последний раз обновлялась из реестра |
Непустой context означает контекстный источник:
он отдаёт данные той сущности, которую сейчас показывают, и годится только для
документа, чей вид даёт такое окружение. В allowedSources такие источники
не перечисляются.
Поля типа результата
Заголовок раздела «Поля типа результата»| Поле | Что |
|---|---|
id |
строковый идентификатор, он же resultType слота |
schema_json |
JSON-схема структуры данных, которые придут в data.<слот> |
stub |
пример данных той же формы — на нём рисуется предпросмотр |
synced_at |
дата синхронизации |
Как подобрать источник для слота
Заголовок раздела «Как подобрать источник для слота»- Понять, какие данные нужны блоку, и найти подходящий тип результата
(
GET /api/v1/data-result-types). - Посмотреть его
schema_jsonиstub— по ним пишется шаблон. - Выбрать источники с этим
result_type_id(GET /api/v1/data-sources) и положить подходящие по смыслу с пустымcontextвallowedSources. Источники с непустымcontextпропустить: их редактор предложит сам на подходящем документе. - Открыть
params_schemaвыбранных источников — оттуда берутся имена и типы параметров привязки.
curl -H "Authorization: Bearer pb_..." \ 'https://page-craft.4partners.io/api/v1/data-sources?limit=50&offset=0'{ "data": [ { "id": "catalog.products", "result_type_id": "product_list", "title": "Товары рубрики", "description": "Список товаров выбранной рубрики", "params_schema": { "type": "object", "properties": { "rubric_id": { "type": "integer", "title": "Рубрика" }, "limit": { "type": "integer", "title": "Сколько показать", "default": 8 }, "sort": { "type": "string", "enum": ["popular", "new", "price"] } } }, "synced_at": "2026-05-19T12:00:00+00:00" } ], "total": 12, "limit": 50, "offset": 0}Подписи в интерфейсе
Заголовок раздела «Подписи в интерфейсе»Человеческие названия берутся из самого реестра стандартными полями JSON Schema:
title и description у источника и у каждого параметра в params_schema.
Варианты enum подписываются расширением x-enumTitles — параллельным массивом
строк того же порядка:
{ "sort": { "type": "string", "title": "Сортировка", "enum": ["popular", "new", "price"], "x-enumTitles": ["Популярные", "Новинки", "По цене"] }}Поля необязательные: без них интерфейс покажет технический ключ. Значениями всегда остаются технические ключи, поэтому подписи ни на что, кроме отображения, не влияют. У типа результата верхнего уровня подписей в протоколе нет вообще — виден только идентификатор.
Ссылки $ref и $stub
Заголовок раздела «Ссылки $ref и $stub»Повторяющиеся структуры (цена, изображение) выносятся в отдельный тип результата и переиспользуются по ссылке:
- в
schema_json—{"$ref": "#/resultTypes/price_dto"}; - в
stub— парный маркер{"$stub": "#/resultTypes/price_dto"}.
{ "items": [ { "name": "Кофеварка", "variation": { "price": { "$stub": "#/resultTypes/price_dto" }, "oldPrice": { "$stub": "#/resultTypes/price_dto" } } } ]}После разворачивания price превращается в данные типа price_dto —
{ "amount": 2990, "currency": "RUB", "formatted": "2 990 ₽" }.
Разворачивает ссылки клиент: редактор догружает недостающие типы рекурсивно и
использует их для подсказок data.* и для предпросмотра. API отдаёт схемы как есть,
поэтому при работе через REST ссылки нужно разрешать самостоятельно. Граничные
случаи безопасны: $ref на несуществующий тип просто не даёт подсказок, $stub
на тип без заглушки подставляет null, цикл обрывается.
Эндпоинты
Заголовок раздела «Эндпоинты»| Метод и путь | Назначение |
|---|---|
GET /api/v1/data-sources |
список источников, limit (1–200, по умолчанию 50) и offset |
GET /api/v1/data-sources/{id} |
один источник целиком |
GET /api/v1/data-result-types |
список типов результата с той же пагинацией |
GET /api/v1/data-result-types/{id} |
тип результата со schema_json и stub |
Списки обёрнуты в { data, total, limit, offset }, детальные ответы — в
{ source: … } и { result_type: … }. Аутентификация — API-ключ в заголовке
Authorization: Bearer pb_….
Откуда берутся записи
Заголовок раздела «Откуда берутся записи»Реестр наполняется синхронизацией с витриной: администратор PageCraft запускает её вручную (расписания и вебхуков нет). Записи опознаются по строковому идентификатору, поэтому повторная синхронизация обновляет существующую запись, а не плодит копии.
Исчезнувшие из реестра записи не удаляются, а помечаются устаревшими: на них могут ссылаться схемы блоков и привязки на уже опубликованных страницах, и удаление превратило бы их в ссылки в никуда.
Истории изменений реестр не хранит: узнать, что у типа результата поменялась схема, можно только сравнив её с тем, на что рассчитывал шаблон блока.
Источники: backend/src/Controller/V1/DataSource/,
backend/src/Controller/V1/DataResultType/,
backend/src/Entity/DataSource.php, backend/src/Entity/DataResultType.php,
backend/src/Service/SourcesSyncService.php,
backend/src/Service/BlockSchemaValidator.php,
front/src/lib/liquidAnalyze.ts (collectRefs, resolveStub),
front/src/components/PageEditor/BindingSlotForm.tsx.