• Docs
        • Документация OnPress v2
            • Документация OnPress v2
              • Как устроена платформа
              • Быстрый старт
              • Доступ, роли и выбор сайта
                • Страницы
                  • Frontmatter: все поля
                  • Синтаксис markdown
                  • Языки и переводы страниц
                • Фреймы
                  • Вставки onpress/
                  • Бинды data-op-bind
                  • Сборка страницы и статическая копия
                • Готовые фреймы
                  • Фрейм assistant: страница с чатом ассистента
                  • Фрейм outline: оглавление в тексте
                  • Фрейм faq: вопросы из текста страницы
                  • Фрейм article: статья
                  • Фрейм docs: документация
                  • Фрейм site__header: шапка сайта
                  • Фрейм site__footer: подвал сайта
                  • Фрейм article__faq: вопросы из набора
                  • Фрейм landing: лендинг ассистента
                  • Фрейм assistant__chat: чат обычной разметкой
                  • Фрейм site__404: страница «не найдено»
                  • Фрейм news: лента новостей
                  • Фрейм news__category: рубрика новостей
                  • Фрейм news__post: новость
                  • Фрейм news__more: читайте ещё
                  • Фрейм news__share: поделиться
                  • Фрейм author__page: страница автора
                  • Фрейм author__byline: подпись автора
                  • Фрейм author__card: карточка автора
                  • Фрейм author__avatar: аватар автора
                  • Фрейм author__socials: соцсети автора
                  • Фрейм author__head: объявление набора автора
                  • Фрейм home: главная-документ
                  • Фрейм pricing: тарифы
                • Наборы данных и системные источники
                  • Повторитель onpress/repeat
              • Стили и оформление
              • Меню
              • Сайдбар документации
              • Языки сайта
              • Настройки, главная и кэш
              • SEO
              • Медиа
              • Сайты и домены
              • Пользователи и профиль
              • Дашборд и вход
                • Рецепты
                  • Сайт с нуля
                  • Раздел документации
                  • Лендинг из конструктора
                  • FAQ на странице
                  • Свой фрейм из готового
                  • Многоязычный сайт
                  • Поменять меню
                  • Перенести страницу
                  • Картинки в статье
                  • Список из данных
                  • Сменить оформление
                • Справочник API
                  • Справочник: страницы
                  • Справочник: переводы
                  • Справочник: фреймы
                  • Справочник: данные
                  • Справочник: меню
                  • Справочник: сайдбар документации
                  • Справочник: стили
                  • Справочник: настройки, главная, кэш
                  • Справочник: языки
                  • Справочник: SEO
                  • Справочник: медиа
                  • Справочник: сайты
                  • Справочник: пользователи и профиль
                  • Справочник: вход и служебное
                • Ошибки и частые проблемы
                  • Коды ошибок
        • Старая документация v1
            • Старая документация v1
              • Начало
              • Привязка домена
              • Виджеты
              • Структура ссылок
              • Connector.js
              • Шапка
              • Подвал
              • Мультиязычность
              • Меню
              • Как настроить стили сайта через Design
              • Schema разметка
              • Open Graph
              • Аналитика
              • FAQ
              • Robots.txt
              • Sitemap
OnPress OnPress
  • Документация
  • Контакты
Войти
    • Docs
        • Документация OnPress v2
            • Документация OnPress v2
              • Как устроена платформа
              • Быстрый старт
              • Доступ, роли и выбор сайта
                • Страницы
                  • Frontmatter: все поля
                  • Синтаксис markdown
                  • Языки и переводы страниц
                • Фреймы
                  • Вставки onpress/
                  • Бинды data-op-bind
                  • Сборка страницы и статическая копия
                • Готовые фреймы
                  • Фрейм assistant: страница с чатом ассистента
                  • Фрейм outline: оглавление в тексте
                  • Фрейм faq: вопросы из текста страницы
                  • Фрейм article: статья
                  • Фрейм docs: документация
                  • Фрейм site__header: шапка сайта
                  • Фрейм site__footer: подвал сайта
                  • Фрейм article__faq: вопросы из набора
                  • Фрейм landing: лендинг ассистента
                  • Фрейм assistant__chat: чат обычной разметкой
                  • Фрейм site__404: страница «не найдено»
                  • Фрейм news: лента новостей
                  • Фрейм news__category: рубрика новостей
                  • Фрейм news__post: новость
                  • Фрейм news__more: читайте ещё
                  • Фрейм news__share: поделиться
                  • Фрейм author__page: страница автора
                  • Фрейм author__byline: подпись автора
                  • Фрейм author__card: карточка автора
                  • Фрейм author__avatar: аватар автора
                  • Фрейм author__socials: соцсети автора
                  • Фрейм author__head: объявление набора автора
                  • Фрейм home: главная-документ
                  • Фрейм pricing: тарифы
                • Наборы данных и системные источники
                  • Повторитель onpress/repeat
              • Стили и оформление
              • Меню
              • Сайдбар документации
              • Языки сайта
              • Настройки, главная и кэш
              • SEO
              • Медиа
              • Сайты и домены
              • Пользователи и профиль
              • Дашборд и вход
                • Рецепты
                  • Сайт с нуля
                  • Раздел документации
                  • Лендинг из конструктора
                  • FAQ на странице
                  • Свой фрейм из готового
                  • Многоязычный сайт
                  • Поменять меню
                  • Перенести страницу
                  • Картинки в статье
                  • Список из данных
                  • Сменить оформление
                • Справочник API
                  • Справочник: страницы
                  • Справочник: переводы
                  • Справочник: фреймы
                  • Справочник: данные
                  • Справочник: меню
                  • Справочник: сайдбар документации
                  • Справочник: стили
                  • Справочник: настройки, главная, кэш
                  • Справочник: языки
                  • Справочник: SEO
                  • Справочник: медиа
                  • Справочник: сайты
                  • Справочник: пользователи и профиль
                  • Справочник: вход и служебное
                • Ошибки и частые проблемы
                  • Коды ошибок
        • Старая документация v1
            • Старая документация v1
              • Начало
              • Привязка домена
              • Виджеты
              • Структура ссылок
              • Connector.js
              • Шапка
              • Подвал
              • Мультиязычность
              • Меню
              • Как настроить стили сайта через Design
              • Schema разметка
              • Open Graph
              • Аналитика
              • FAQ
              • Robots.txt
              • Sitemap
Документация OnPress v2
Markdown
Открыть в ИИ
  • Открыть в ChatGPT
  • Открыть в Claude
  • Открыть в Gemini
  • Открыть в Perplexity
  • Открыть в Grok
  • Открыть в DeepSeek

Страницы

Страница — единственное, что на сайте открывается по адресу. В v2 её пишут одним способом — markdown с frontmatter в POST /pages/markdown — и читают тремя: списком, целиком и выгрузкой обратно в markdown. Отдельные поля (выдержку и фрейм) меняет PATCH, убирает DELETE.

Всё ниже — ручки сайта, то есть пути вида $API/site/$SITE/pages…. Полные параметры и ответы — в справочнике страниц.

Страница = markdown + фреймы

В теле страницы в идеале только markdown и вызовы фреймов. Разметка живёт во фреймах, данные — в теле и во frontmatter. Тогда текст читается и правится как текст, а вид блока меняется в одном фрейме сразу на всех страницах.

Пример — демо-страница bota.chat/base/canva/. Чат ассистента там стоит во фрейме над телом, а тело первой строкой передаёт ему агента вставкой onpress/assistant:

---
name: "Canva"
frame: "article"
data.rating: 5
---

<!-- onpress/assistant {"id":"x8OA7Azs4hBy","agent":"canva","agent_view":"profile"} /-->

# Canva: …

<!-- onpress/frame {"name":"rating"} /-->

<!-- onpress/frame {"name":"outline"} /-->

Текст статьи обычным markdown.

## FAQ

<!-- onpress/frame {"name":"faq"} -->
### Вопрос?

Ответ.
<!-- /onpress/frame -->

Фрейм rating — пять звёзд и число из frontmatter в атрибуте. Условий во фрейме нет: закраску делает CSS по значению атрибута.

<div class="rating" data-op-bind='{"data-rating":"page.data.rating"}'><span class="rating__star">★</span><span class="rating__star">★</span><span class="rating__star">★</span><span class="rating__star">★</span><span class="rating__star">★</span></div>
.rating{display:flex;gap:2px;color:var(--line-color)}
.rating[data-rating="1"] .rating__star:nth-child(-n+1),
.rating[data-rating="2"] .rating__star:nth-child(-n+2),
.rating[data-rating="3"] .rating__star:nth-child(-n+3),
.rating[data-rating="4"] .rating__star:nth-child(-n+4),
.rating[data-rating="5"] .rating__star:nth-child(-n+5){color:#f5a524}

Это только визуальный пример: рейтинг, который страница поставила себе сама, без отзывов, размечать schema.org нельзя.

Фрейм outline — оглавление в теле:

<div class="not-prose"><!-- onpress/outline {"shell":"spoiler"} /--></div>

not-prose нужен, когда оглавление стоит в теле внутри колонки .prose: иначе на список ложатся стили текста. Оглавление в теле собирается после всего тела, заголовки и якоря в нём те же, что у оглавления во фрейме страницы.

Фрейм faq получает вопросы слотом и выводит аккордеон и FAQPage — см. рецепт FAQ. Значения frontmatter во фреймах — page.data.*, параметры и слот — вставка onpress/frame.

Публикация

curl -s -X POST "$API/site/$SITE/pages/markdown" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d "$(jq -n --rawfile md page.md '{markdown: $md}')"

page.md:

---
name: "Тарифы"
slug: "tarify"
url: "/tarify/"
lang: "ru"
status: "publish"
frame: "article"
seo_title: "Тарифы OnPress"
seo_description: "Сколько стоит OnPress и что входит в каждый тариф."
excerpt: "Три тарифа и что в них входит."
---

Текст страницы в **markdown**.

Все поля frontmatter, их смысл и то, что с ними происходит, — на странице frontmatter. Что можно писать в теле — в синтаксисе markdown.

Ответ говорит всё, что нужно проверить после записи:

{
  "success": true,
  "updated": false,
  "id": 6428,
  "status": "publish",
  "lang": "ru",
  "parent": 0,
  "url": "/tarify/",
  "link": "https://example.onpress.pro/tarify/",
  "visible": true,
  "translations": { "ru": 6428 },
  "frame": { "id": "c33c7d69d5a35456", "slug": "article", "meta_key": "_onpress_frame" },
  "printed": { "how": "on_request", "url": "/tarify/", "link": "https://example.onpress.pro/tarify/", "frame": { "id": "c33c7d69d5a35456", "slug": "article", "renders_on_request": true } },
  "warnings": [],
  "edit_url": "https://example.onpress.pro/wp-admin/post.php?post=6428&action=edit",
  "view_url": "https://example.onpress.pro/tarify/",
  "preview_url": null,
  "meta": { "name": "Тарифы", "slug": "tarify", "…": "…" },
  "blocks": [ { "blockName": "core/paragraph", "…": "…" } ]
}
ПолеЧто проверять
updatedfalse — создана новая страница, true — обновлена существующая
url / linkпуть страницы в дереве и адрес, по которому её отдаёт сайт (с префиксом языка, если язык не основной)
visibleвидит ли страницу посетитель: false у черновика и у страницы под неопубликованным родителем
printed.howкак страница отдаётся: static, on_request, not_published или theme (фрейма нет — на сайте v2 это 404), подробно в сборке
warningsвсё, что сделано не так, как просили: проигнорированный template, незнакомые ключи frontmatter, незаписанные служебные ключи с _, сменившийся слаг, неопубликованный родитель
slug_changedесть, только если записанный слаг отличается от запрошенного (занят в том же языке под тем же родителем)
preview_urlу неопубликованной страницы — адрес вида /?page_id=…, у опубликованной null

Пробного прогона у публикации нет. dry_run: true в теле даёт 400 dry_run_not_supported: публикация всегда пишет. Чтобы посмотреть результат до выхода в свет, публикуйте с status: draft — в ответе будут блоки, адрес и preview_url.

Какую страницу обновит публикация

Публикация — это upsert. Существующая страница ищется так:

  1. Есть id во frontmatter и это страница — обновляется она. Если её язык не совпадает с lang — 409 lang_mismatch: так защищён оригинал от перевода, в который по ошибке скопировали id (для переводов есть translation_of).
  2. Иначе ищется страница с тем же слагом под тем же родителем и в том же языке, среди статусов publish, draft, pending, private. Нашлась одна — обновляется она. Нашлось несколько — 409 ambiguous_page со списком matches, уточните id или lang. Страница без языка (осталась с тех времён, когда язык не проставлялся) считается своей для любого языка.
  3. Не нашлась — создаётся новая, в конец списка своих соседей.

Поиск по слагу отключается slug_lookup: false — тогда без id всегда создаётся новая страница.

Следствие, которое ломает переносы. Родитель — часть ключа поиска. Если опубликовать страницу /a/page/ с url: "/b/page/" без id, API не найдёт её под b и создаст вторую страницу, а старая останется на месте. Перенос страницы в другую ветку делается с id во frontmatter или ручками сайдбара — см. рецепт переноса.

Адрес и дерево

Адрес страницы — цепочка слагов её родителей и её собственного слага. Задаётся полем url: полный путь страницы, последний сегмент — сама страница. Все сегменты кроме последнего должны быть существующими страницами (в том же языке, если он есть) — иначе 422 parent_not_found с именем сегмента. Флаг create_missing_parents: true создаёт недостающих родителей пустыми черновиками — но черновик-родитель делает адрес потомка недоступным, и ответ об этом предупреждает.

Слаг берётся из поля slug, а не из url. Если slug не указан, он собирается из name транслитерацией — и последний сегмент url при этом не используется:

---
name: "Дочерняя страница"
url: "/razdel/drugoe-imya/"
---

даст адрес /razdel/dochernyaya-stranica/. Всегда пишите slug и url согласованно. Языковой префикс в url (/ru/razdel/…) распознаётся по реальному списку языков сайта и не считается уровнем дерева; язык страницы при этом задаёт только поле lang. Схема и домен в url — 422 absolute_url_in_path.

Порядок среди соседей (menu_order) при создании — последним; дальше он меняется ручками сайдбара (для страниц документации) и влияет на системные источники pages.* и на onpress/pager.

Слаг уникален среди соседей одного языка. Занятый слаг получает суффикс (tarify-2), и ответ сообщает об этом полем slug_changed и предупреждением — адрес уехал, это надо заметить.

Статусы

publish, draft, pending, private, future. По умолчанию publish. Неизвестный статус — 400 invalid_status со списком допустимых. Черновик и отложенная страница не отдаются по адресу, приватная видна только вошедшим администраторам. Страница видна посетителю, только если опубликованы она и все её предки.

Чтение

Список:

curl -s -H "Authorization: Bearer $OP_TOKEN" \
  "$API/site/$SITE/pages?lang=ru&parent=0&per_page=50&orderby=menu_order" \
  | jq '{lang, total, total_pages, items: [.items[] | {id, url, status, frame: .frame.slug}]}'

Фильтры: lang (или all), status (CSV или any — с корзиной), parent (id, слаг, путь или 0 для верхнего уровня), frame (слаг, id или none), slug, search (по заголовку и слагу, не по телу), page, per_page (до 200), orderby (menu_order, title, date, modified, id, slug), order. Без lang фильтра по языку нет, и ответ прямо говорит "lang": "all".

Одна страница целиком — паспорт, родители, группа переводов, frontmatter, вся значимая мета и тело в markdown:

curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/pages/tarify" | jq '{page: .page | {id, url, frame, seo, frontmatter}, markdown}'

{ref} в пути — id, слаг или путь, где слеши заменены тильдой: /docs/api/ пишется docs~api, русская /ru/o-nas/ — ru~o-nas. Параметры: lang — в каком языке искать и с чем сверить; markdown=false — не выгружать тело (быстрее).

Только тело в markdown — ровно то, что принимает публикация:

curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/pages/tarify/markdown" | jq -r .markdown > tarify.md

Выгрузка отдаёт frontmatter с id, всеми документированными полями, excerpt, frame (всегда, даже пустым) и вашими собственными ключами в порядке последней публикации. Круг «выгрузил — поправил — залил» не меняет ни байта. С ?as=translation_source вместо id приходит translation_of, а status не приходит — заготовка под перевод.

Правка отдельных полей

PATCH /pages/{ref} меняет выдержку и фрейм, не трогая тело:

curl -s -X PATCH "$API/site/$SITE/pages/tarify" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"excerpt": "Три тарифа и что в них входит.", "frame": "article"}' \
  | jq '{changed, frame, static, republish: .republish.status}'

frame: null (или "", "none", false) снимает фрейм — на сайте v2 страница после этого отвечает 404. Смена фрейма сразу приводит в порядок статическую копию страницы, исход — в поле static. Остальные поля (заголовок, слаг, адрес, SEO, тело) меняются только публикацией markdown.

Удаление

# план: что будет удалено, ничего не трогая
curl -s -X DELETE "$API/site/$SITE/pages/tarify?dry_run=true" -H "Authorization: Bearer $OP_TOKEN" | jq '{mode, targets: [.targets[] | {id, url}]}'

# в корзину (по умолчанию)
curl -s -X DELETE "$API/site/$SITE/pages/tarify" -H "Authorization: Bearer $OP_TOKEN" | jq '{mode, restore}'

# безвозвратно
curl -s -X DELETE "$API/site/$SITE/pages/tarify?force=true" -H "Authorization: Bearer $OP_TOKEN" | jq '{mode}'

Страница с детьми — 409 page_has_children со списком; with_children=true удаляет поддерево снизу вверх. Главную страницу и главные страницы языков удалить нельзя (409 front_page_delete) — сначала переназначьте главную. Корзина сохраняет страницу в группе переводов, безвозвратное удаление выводит её оттуда. Статическая копия снимается в обоих случаях. Корзина видна в GET /pages?status=trash.

Язык страницы

На сайте с Polylang у страницы всегда есть язык: названный в lang или язык сайта по умолчанию (тогда ответ предупреждает). Страница без языка на многоязычном сайте не открывается вовсе — WordPress уводит её редиректом саму на себя. Если такие страницы остались, их чинит POST /pages/language:

curl -s -X POST "$API/site/$SITE/pages/language" \
  -H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
  -d '{"missing": true, "dry_run": true}' | jq '{lang, total, changed}'

Переводы, группы и hreflang — на странице языки и переводы страниц.

Частые ошибки

КодПричинаЧто делать
markdown_required (400)нет поля markdown или это не строкатело — {"markdown": "…"}
parent_not_found (422)сегмент url — не существующая страница этого языкасоздать родителя или create_missing_parents: true
absolute_url_in_path (422)в url схема или доментолько путь
ambiguous_page (409)слаг есть у нескольких страницid во frontmatter или lang
lang_mismatch (409)id указывает на страницу другого языкадля перевода — translation_of вместо id
unknown_language (422)lang нет на сайтесписок в languages
invalid_status (400)статус не из спискаpublish, draft, pending, private, future
frame_single (400)во frame списокодин слаг или id
frame_not_found (404)фрейма нет на этом сайтеGET /frames
post_type_not_supported (501)type не pagev2 пишет только страницы
domain_mismatch (409)domain во frontmatter — другой сайтубрать domain, сайт выбирается адресом запроса
page_language_mismatch (409)id или путь с префиксом называют страницу другого языка, чем langадресовать страницу нужного языка или убрать lang

Ссылка и язык. GET, PATCH и DELETE /pages/{ref} находят страницу одинаково. Голый слаг с lang ищется среди страниц этого языка: PATCH $API/site/$SITE/pages/tarify с {"lang": "ru"} правит русскую /ru/tarify/, даже если у английской тот же слаг; русской нет — 404 page_not_found с языком. Голый слаг без lang — страница основного языка. Id и путь с префиксом называют страницу сами, и lang с ними только сверяется.

arrow_backНазад
Доступ, роли и выбор сайта
Далееarrow_forward
Frontmatter: все поля
На этой странице
  • Страница = markdown + фреймы
    • Публикация
      • Какую страницу обновит публикация
        • Адрес и дерево
          • Статусы
            • Чтение
              • Правка отдельных полей
                • Удаление
                  • Язык страницы
                    • Частые ошибки
                    OnPress
                    OnPress
                    ИП Зуев И.В. ИНН: 360408359441
                    © 2026
                    политика конфиденциальности публичная оферта
                    • visa
                    • mastercard
                    • sber
                    • tpay