Меню
Эндпоинты меню сайта: пункты меню в области темы как системные данные menu.{область} и сами меню — создание, переименование, удаление, постановка в область, правка пунктов и порядок; как меню устроены для человека — Меню.
Во всех примерах API — https://onpress.pro/api/v2, SITE — id сайта (SITE_ID), OP_TOKEN — токен op_XXXX. Права на всех эндпоинтах страницы — администратор сайта. Как выбирается сайт и в какой форме приходят отказы — Доступ и токен.
Области темы: header, footer_1, footer_2, footer_3. {ref} меню в адресе — id, слаг, имя или область с тильдой (~header — меню, которое сейчас стоит в шапке; принимается и @header). lang выбирает меню языка, theme — карту областей другой темы. Каждая запись, кроме переименования, пересобирает фреймы с меню и сбрасывает кэш их страниц — поле rebaked.
Пункт в теле записи: {"page": id|слаг|путь} — ссылка на страницу сайта, или {"url": "…"} — любой адрес; плюс title, target, classes (строка через пробел), children (вложенные пункты). Голое значение вместо объекта — ссылка на страницу. Путь в url дополняется адресом сайта. Пункт на неопубликованную страницу — отказ 409 menu_items_invalid, пропустить его — "allow_invalid": true.
GET /data/menu.{область}
Отдаёт пункты меню, которое стоит в области, деревом. Например, прочитать английское меню шапки:
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/data/menu.header?lang=en"
{
"success": true,
"site_id": "x9HTLHECq",
"name": "menu.header",
"origin": "system",
"writable": true,
"write": { "method": "PUT", "at": "/data/menu.header", "…": "…" },
"total": 2,
"meta": { "menu_id": 83, "invalid_items": 0 },
"items": [
{ "id": 6011, "title": "Docs", "url": "/en/docs/", "type": "post_type", "object": "page", "object_id": 4934, "target": "", "classes": [], "description": "", "parent": 0, "order": 1, "children": [] },
{ "id": 5603, "title": "Contacts", "url": "/en/contacts/", "type": "post_type", "object": "page", "object_id": 5600, "target": "", "classes": [], "description": "", "parent": 0, "order": 2, "children": [] }
]
}
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
lang | string | основной язык | меню этого языка в области |
theme | string | тема сайта | карта областей другой темы |
Пункт: id, title, url, type (post_type — страница, custom — свой адрес), object и object_id — страница пункта, target, classes, parent, order, children. В meta — menu_id меню в области и invalid_items — сколько пунктов ведут на страницы, которых посетитель не увидит.
PUT /data/menu.{область}
Заменяет пункты меню в области целиком; то же делает PUT /menus/~{область}/items. Например, положить в английскую шапку две ссылки:
curl -s -X PUT "$API/site/$SITE/data/menu.header" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"lang": "en", "items": [{"page": "/en/docs/", "title": "Docs"}, {"page": "/en/contacts/"}]}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
items | array | — | дерево пунктов, обязательно; [] очищает меню |
lang | string | основной язык | меню этого языка |
allow_invalid | bool | false | пропустить пункты на неопубликованные страницы |
theme | string | тема сайта | карта областей другой темы |
Ответ — как у PUT /menus/{ref}/items, плюс source и rebaked. Области без меню запись не создаёт: сначала POST /menus с location.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
bad_menu_items | 400 | нет items или это не массив | пришлите дерево пунктов |
menu_not_assigned | 404 | в области нет меню | создайте меню с location |
menu_items_unresolved | 409 | пункт не нашёл страницу; разбор в errors | исправьте page |
menu_items_invalid | 409 | пункт ведёт на неопубликованную страницу; список в invalid | опубликуйте страницу или allow_invalid |
wrong_method_for_source | 405 | PATCH вместо PUT | отправьте PUT |
system_source_not_deletable | 409 | DELETE /data/menu.{область} | очистите меню PUT с "items": [] или снимите его с области |
GET /menus
Отдаёт все меню сайта и где каждое стоит. Например:
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/menus"
{
"success": true,
"site_id": "x9HTLHECq",
"theme": "onpress-v2",
"locations": ["header", "footer_1", "footer_2", "footer_3"],
"default_lang": "en",
"read_items_at": "/data/menu.{location}",
"total": 14,
"menus": [
{ "id": 83, "name": "header en", "slug": "header-en", "items": 3, "assigned": [ { "location": "header", "lang": "en" } ] },
{ "id": 87, "name": "footer center en", "slug": "footer-center-en", "items": 9, "assigned": [] }
]
}
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
theme | string | тема сайта | карта областей другой темы |
menus[].items — число пунктов, assigned — области и языки, где меню стоит.
POST /menus
Создаёт меню, сразу ставит его в область и наполняет пунктами. Например, меню шапки на английском:
curl -s -X POST "$API/site/$SITE/menus" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"name": "header en", "location": "header", "lang": "en", "items": [{"page": "/en/docs/", "title": "Docs"}, {"url": "https://onpress.pro/", "title": "OnPress", "target": "_blank", "children": [{"page": "/en/contacts/"}]}]}'
{
"success": true,
"site_id": "x9HTLHECq",
"theme": null,
"menu": { "id": 171, "name": "header en", "slug": "header-en", "items": 3 },
"items": [
{ "id": 6433, "at": "0", "title": "Docs", "type": "post_type", "page": 4934, "url": "/en/docs/", "parent": 0, "order": 1, "valid": true },
{ "id": 6434, "at": "1", "title": "OnPress", "type": "custom", "page": null, "url": "https://onpress.pro/", "parent": 0, "order": 2, "valid": true },
{ "id": 6435, "at": "1.0", "title": "Contacts", "type": "post_type", "page": 5600, "url": "/en/contacts/", "parent": 6434, "order": 3, "valid": true }
],
"invalid": [],
"rebaked": { "status": "ok", "total": 9, "…": "…" }
}
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
name | string | — | название меню, обязательно |
slug | string | из названия | слаг, делается уникальным |
location | string | — | сразу поставить в область |
lang | string | основной язык | язык для карты областей |
items | array | — | сразу наполнить деревом пунктов |
allow_invalid | bool | false | пропустить пункты на неопубликованные страницы |
theme | string | тема сайта | тема для карты областей |
at — место пункта в присланном дереве: "1.0" — первый вложенный пункт второго.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
menu_name_required | 400 | нет name | пришлите название |
bad_items | 400 | items не массив | пришлите дерево пунктов |
unknown_location | 400 | такой области нет; список в locations | возьмите область из списка |
unknown_language | 400 | такого языка на сайте нет | возьмите слаг из GET /data/site.languages |
polylang_inactive | 409 | lang на одноязычном сайте | уберите lang |
menu_items_unresolved | 409 | пункт не нашёл страницу; разбор в errors | исправьте page |
menu_items_invalid | 409 | пункт ведёт на неопубликованную страницу; список в invalid | опубликуйте страницу или allow_invalid |
menu_assignment_not_stored | 500 | область не записалась | повторите запрос |
PATCH /menus/{ref}
Переименовывает меню; пункты и области не меняются, фреймы не пересобираются. Например:
curl -s -X PATCH "$API/site/$SITE/menus/header-en" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"name": "Header EN"}'
{ "success": true, "site_id": "x9HTLHECq", "menu": { "id": 171, "term_taxonomy_id": 171, "name": "Header EN", "slug": "header-en", "count": 3 } }
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
name | string | — | новое название |
slug | string | — | новый слаг, уникальный среди меню |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
nothing_to_update | 400 | нет ни name, ни slug | пришлите поле |
menu_not_found | 404 | меню нет | возьмите id из GET /menus |
ambiguous_menu | 409 | имя подходит нескольким меню | адресуйте меню по id |
DELETE /menus/{ref}
Удаляет меню со всеми пунктами и снимает его со всех областей. Например:
curl -s -X DELETE "$API/site/$SITE/menus/171" -H "Authorization: Bearer $OP_TOKEN"
{ "success": true, "site_id": "x9HTLHECq", "deleted": { "id": 171, "name": "Header EN", "slug": "header-en" }, "removed_items": 3, "freed_locations": [ { "location": "header", "lang": "en" } ], "rebaked": { "…": "…" } }
| Код | Статус | Когда | Что делать |
|---|---|---|---|
menu_not_found | 404 | меню нет | возьмите id из GET /menus |
ambiguous_menu | 409 | имя подходит нескольким меню | адресуйте меню по id |
PUT /menus/{ref}/location
Ставит меню в область; меню, которое стояло там раньше, остаётся на сайте. Например, поставить меню 171 в шапку английской версии:
curl -s -X PUT "$API/site/$SITE/menus/171/location" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"location": "header", "lang": "en"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
location | string | — | область, обязательно: header, footer_1, footer_2, footer_3 |
lang | string | основной язык | язык области |
theme | string | тема сайта | тема для карты областей |
Записанные области перечитываются и сверяются с присланными.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
location_required | 400 | нет location или пустая строка | снять меню с области — DELETE /menus/{ref}/location |
unknown_location | 400 | такой области нет; список в locations | возьмите область из списка |
unknown_language | 400 | такого языка на сайте нет | возьмите слаг из GET /data/site.languages |
menu_not_found | 404 | меню нет | возьмите id из GET /menus |
polylang_inactive | 409 | lang на одноязычном сайте | уберите lang |
menu_assignment_not_stored | 500 | область не записалась; что прочитано — в read_back | повторите запрос |
DELETE /menus/{ref}/location
Снимает меню с области, само меню остаётся. Например, убрать меню из английской шапки:
curl -s -X DELETE "$API/site/$SITE/menus/~header?lang=en" -H "Authorization: Bearer $OP_TOKEN"
{ "success": true, "site_id": "x9HTLHECq", "theme": "onpress-v2", "menu": { "id": 171, "name": "Header EN", "slug": "header-en" }, "freed_locations": [ { "location": "header", "lang": "en", "via": "polylang" } ], "rebaked": { "…": "…" } }
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
location | string | область из ~область в адресе; у меню по id или слагу — все | с какой области снять |
lang | string | все языки | с какого языка снять |
theme | string | тема сайта | тема для карты областей |
Параметры принимаются в строке запроса или в теле.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
unknown_location | 400 | такой области нет | возьмите область из GET /menus |
unknown_language | 400 | такого языка на сайте нет | возьмите слаг из GET /data/site.languages |
menu_not_found | 404 | меню нет | возьмите id из GET /menus |
menu_not_in_location | 404 | меню не стоит в этой области; где стоит — в standing | проверьте location и lang |
polylang_inactive | 409 | lang на одноязычном сайте | уберите lang |
PUT /menus/{ref}/items
Заменяет дерево пунктов меню целиком. Например:
curl -s -X PUT "$API/site/$SITE/menus/171/items" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"items": [{"page": "/en/docs/", "title": "Docs"}, {"page": "/en/contacts/"}]}'
{
"success": true,
"site_id": "x9HTLHECq",
"menu": { "id": 171, "name": "Header EN", "slug": "header-en" },
"total": 2,
"invalid": [],
"items": [
{ "id": 6437, "at": "0", "title": "Docs", "type": "post_type", "page": 4934, "url": "/en/docs/", "parent": 0, "order": 1, "valid": true },
{ "id": 6438, "at": "1", "title": "Contacts", "type": "post_type", "page": 5600, "url": "/en/contacts/", "parent": 0, "order": 2, "valid": true }
],
"read_items_at": "/data/menu.{location}",
"rebaked": { "…": "…" }
}
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
items | array | — | дерево пунктов, обязательно |
allow_invalid | bool | false | пропустить пункты на неопубликованные страницы |
lang, theme | string | — | язык и тема для ~область |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
bad_items | 400 | нет items или это не массив | пришлите дерево пунктов |
menu_not_found | 404 | меню нет | возьмите id из GET /menus |
menu_not_assigned | 404 | в области ~область нет меню | поставьте меню в область |
menu_items_unresolved | 409 | пункт не нашёл страницу; разбор в errors | исправьте page |
menu_items_invalid | 409 | пункт ведёт на неопубликованную страницу; список в invalid | опубликуйте страницу или allow_invalid |
POST /menus/{ref}/items
Добавляет один пункт в конец уровня; parent — id пункта, под который добавить. Тело — {"item": {…}} или сам пункт. Например:
curl -s -X POST "$API/site/$SITE/menus/171/items" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"item": {"page": "/en/pricing/", "title": "Pricing"}}'
{ "success": true, "site_id": "x9HTLHECq", "menu": { "id": 171, "name": "Header EN" }, "item": { "id": 6439, "title": "Pricing", "type": "post_type", "page": 5810, "url": "/en/pricing/", "parent": 0, "order": 3, "valid": true }, "total": 3, "rebaked": { "…": "…" } }
| Код | Статус | Когда | Что делать |
|---|---|---|---|
item_target_required | 400 | нет ни page, ни url | пришлите одно из двух |
page_not_found | 404 | страницы нет | проверьте page |
item_not_found | 404 | пункта-родителя нет | возьмите id из GET /data/menu.{область} |
menu_items_invalid | 409 | пункт ведёт на неопубликованную страницу | опубликуйте страницу или allow_invalid |
PATCH /menus/{ref}/items/{id}
Меняет один пункт: title, page, url, target, classes, parent. page превращает пункт в ссылку на страницу, url — в ссылку на свой адрес. Например, переименовать пункт:
curl -s -X PATCH "$API/site/$SITE/menus/171/items/6434" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"title": "OnPress.pro"}'
{ "success": true, "site_id": "x9HTLHECq", "menu": { "id": 171, "name": "Header EN" }, "item": { "id": 6434, "title": { "from": "OnPress", "to": "OnPress.pro" } }, "warnings": [], "rebaked": { "…": "…" } }
В item изменённые поля приходят парой from и to.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
nothing_to_update | 400 | в теле нет ни одного поля | пришлите поле |
item_not_found | 404 | пункта нет | возьмите id из GET /data/menu.{область} |
page_not_found | 404 | страницы нет | проверьте page |
bad_parent | 409 | пункт сам себе родитель | выберите другого родителя |
menu_items_invalid | 409 | пункт ведёт на неопубликованную страницу | опубликуйте страницу или allow_invalid |
DELETE /menus/{ref}/items/{id}
Удаляет пункт вместе с вложенными. Например:
curl -s -X DELETE "$API/site/$SITE/menus/171/items/6434" -H "Authorization: Bearer $OP_TOKEN"
{ "success": true, "site_id": "x9HTLHECq", "menu": { "id": 171, "name": "Header EN" }, "removed": [6434, 6435], "total": 2, "rebaked": { "…": "…" } }
| Код | Статус | Когда | Что делать |
|---|---|---|---|
item_not_found | 404 | пункта нет | возьмите id из GET /data/menu.{область} |
POST /menus/{ref}/reorder
Задаёт порядок пунктов одного уровня. Например, поставить «Pricing» первым:
curl -s -X POST "$API/site/$SITE/menus/171/reorder" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"order": [6439, 6433]}'
{ "success": true, "site_id": "x9HTLHECq", "menu": { "id": 171, "name": "Header EN" }, "parent": 0, "order": [6439, 6433, 6434], "appended": [6434], "rebaked": { "…": "…" } }
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
order | int[] | — | id пунктов уровня в нужном порядке, обязательно |
parent | int | 0 | id пункта-родителя уровня, 0 — верхний уровень |
Неназванные пункты уровня встают после названных — appended.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
bad_reorder | 400 | order не массив id | пришлите список id |
item_not_found | 404 | пункта нет на этом уровне | возьмите id из GET /data/menu.{область} |