Вставки
Вставка — блочный комментарий WordPress в неймспейсе op/, который вносит во фрейм живую разметку: меню, список, текст страницы, другой фрейм. Здесь синтаксис и каждая вставка с атрибутами.
Синтаксис
Фрейм — застывшая разметка, а меню, языки, списки и сама страница меняются. Живые части фрейма — вставки: штатный блочный комментарий WordPress в неймспейсе op/, та же грамматика, которой хранятся все блоки Гутенберга.
<!-- wp:op/menu {"place":"header","depth":1} /-->
Своего языка шаблонов нет. Разбор делает ядровый parse_blocks(), подстановку — render_block(), каждая вставка зарегистрирована register_block_type() по своему block.json. Блочный комментарий невидим в браузере, переживает экспорт из конструктора, не конфликтует с фигурными скобками JS-шаблонизаторов и проходит через markdown-конвертер нетронутым.
Форм две. Самозакрывающаяся вставка кончается на /-->. Вставка с телом пишется парой, и тело — её шаблон или содержимое:
<!-- wp:op/repeat {"source":"faq"} -->
<details><summary data-op-bind='{"text":"item.q"}'></summary></details>
<!-- /wp:op/repeat -->
Атрибуты — JSON сразу после имени; вставка без атрибутов берёт все умолчания. JSON обязан быть валидным, и типичная ловушка — кавычки: двойная кавычка внутри строкового значения ("text":"© "Acme"") ломает JSON, и WordPress молча отбрасывает все атрибуты этой вставки и печатает её с умолчаниями. Ни ошибки, ни предупреждения не будет. Экранируйте кавычку как \u0022 или берите типографские «ёлочки». По той же причине не ставьте в значение --: оно закрывает HTML-комментарий. После заливки сверьте счётчики в inserts ответа и посмотрите на страницу.
Значение внутри атрибута тега (href, src, текст элемента) — не работа вставки, для этого есть бинды.
Где работают
Во фрейме — это их основное место: фрейм печатается на каждый запрос или печётся заранее, и каждая вставка разворачивается. В контенте обычной страницы тоже: вставки — зарегистрированные типы блоков, поэтому markdown-страница может содержать строку <!-- wp:op/frame {"ref":"docs__promo"} /--> или op/callout. В контенте страница берётся из запроса.
Незарегистрированная вставка остаётся комментарием и называется в отчёте печати: вставка op/foo не зарегистрирована, останется комментарием. Вставка, которой нечего печатать, тоже не пропадает молча: она оставляет HTML-комментарий с причиной, например <!-- op/menu: для области «header» меню не назначено -->. Откройте исходный код страницы и ищите <!-- op/. Ниже тексты этих комментариев приведены дословно.
Печать на запросе. Часть вставок зависит от того, какая страница печатается. Фрейм с любой из них получает renders_on_request: true и живёт без испечённой копии, см. Фреймы. У каждой вставки ниже сказано, относится ли она к таким.
| Группа | Вставки |
|---|---|
| Оболочка страницы | op/content, op/frame, op/partial (устарела) |
| Навигация и настройки сайта | op/menu, op/lang-switcher, op/socials, op/footer-columns, op/copyright |
| Списки и данные | op/repeat, op/faq-schema |
| Документация | op/docs-nav, op/outline, op/pager, op/search, op/share-ai |
| Статья | op/featured-image, op/terms |
| Прочее | op/callout, op/assistant |
Оболочка страницы
op/content
Печатает содержимое самой страницы — то место оболочки, куда встаёт текст записи. Печать ровно та же, что у шаблона темы, через the_content, а заголовки получают те же якоря, на которые ссылается op/outline.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
page | 0 | номер страницы; 0 — печатаемая страница |
При пустоте: <!-- op/content: страницы в контексте нет, печатать нечего --> (страницы нет, например при выпечке), <!-- op/content: записи 123 не существует --> и <!-- op/content: вложенный вызов, содержимое печатается только раз -->, когда содержимое оказалось внутри содержимого. Печать на запросе: да.
<article class="article__body"><!-- wp:op/content /--></article>
op/frame
Печатает в этом месте другой фрейм сайта. Единственная связь между фреймами; работает и в контенте страницы.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
ref | "" | слаг или id фрейма; принимаются псевдонимы frame, slug и id |
type | "" | легаси: header, footer или partial по старым дефолтам сайта; только до миграции 233 |
class | "" | обернуть результат в div с этим классом |
Вложенный фрейм печатается из своего исходника в контексте внешнего прогона — та же страница и тот же язык. Защиты: фрейм, который уже печатается, второй раз не печатается (рекурсия), вложенность обрывается на 8 уровнях, за прогон печатается не больше 64 вложенных фреймов. Если вложенный фрейм погашен "empty":"frame", вставка печатает пустую строку. Если вложенный фрейм — целый документ с <!doctype> или <html>, перед ним печатается комментарий-предупреждение.
При пустоте, все в виде <!-- op/frame: … -->: не указан ref — это id или слаг фрейма, фрейма «site__header» на сайте нет, рекурсия, фрейм уже печатается: a → b → a, глубже 8 вложенных фреймов не печатаем, у типа «header» нет назначенного фрейма (легаси; ссылайтесь op/frame {"ref":…}). Печать на запросе: только если на запросе печатается вложенный фрейм.
<!-- wp:op/frame {"ref":"site__header"} /-->
<!-- wp:op/frame {"ref":"article__faq","class":"article__faq-wrap"} /-->
Переименование фрейма переписывает такие ссылки само, см. Фреймы.
op/partial (устарела)
Алиас совместимости op/frame {"type":"partial"}: мета страницы _onpress_frame_partial, затем старый дефолт сайта. Атрибутов нет. Оставлена только для старых фреймов; пишите op/frame {"ref":…}. При пустоте: <!-- op/partial: странице не назначен фрейм-вставка и дефолта у сайта нет -->. Печать на запросе: да.
<!-- wp:op/partial /-->
Навигация и настройки сайта
op/menu
Меню, назначенное области навигации темы, печатается ядровым wp_nav_menu(). Для неосновного языка меню берётся из карты Polylang этого языка. Меню правятся ручками меню.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
place | header | область: header, footer_1, footer_2, footer_3; принимается псевдоним location |
id | "" | id списка; пусто — menu-<слаг меню>; повтор за прогон получает -1, -2 |
display | list | list или dropdown (обёртка details и summary, без JS) |
label | "" | подпись свёрнутого варианта; пусто — «Меню» |
lang | "" | язык меню; пусто — язык печати |
depth | 0 | глубина вложенности, 0 — без ограничения |
class | op-menu | класс списка; у свёрнутого — op-menu--dropdown, op-menu__summary |
При пустоте: <!-- op/menu: для области «header» меню не назначено -->. Печать на запросе: нет; правка меню перепекает фреймы, которые его вставляют.
<nav class="site__nav"><!-- wp:op/menu {"place":"header","depth":1,"class":"site__menu"} /--></nav>
op/lang-switcher
Языки сайта из Polylang. Когда печатается страница, каждая ссылка ведёт на опубликованный перевод этой страницы, а без перевода — на главную языка.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
display | list | list (список ul) или dropdown (details и summary, текущий язык в summary) |
label | "" | aria-label свёрнутого варианта и его запасная подпись |
show | name | name (English, Русский) или slug (EN, RU) |
hide_current | false | не показывать текущий язык |
class | op-lang-switcher | корневой класс; пункты — __item, __link, у текущего is-current и aria-current |
При пустоте: <!-- op/lang-switcher: Polylang не активен -->, <!-- op/lang-switcher: языков нет -->. Печать на запросе: нет.
<div class="site-header__lang"><!-- wp:op/lang-switcher {"class":"oplang","show":"name","display":"dropdown"} /--></div>
op/socials
Ссылки на соцсети из настроек сайта — те же поля, которые пишет ручка настроек: twitter, facebook, telegram, whatsapp, linkedin, instagram, reddit, gitlab, github, youtube, pinterest. Печатаются только заполненные, списком ul с __item и __link--<сеть>.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
place | footer | принимается, но на вывод не влияет |
class | op-socials | корневой класс |
При пустоте: <!-- op/socials: ACF не активен -->, <!-- op/socials: в настройках сайта нет ни одной ссылки -->. Печать на запросе: нет.
<!-- wp:op/socials {"class":"site-footer__socials"} /-->
op/footer-columns
Меню подвала колонками: колонка на область, имя меню — заголовок колонки, само меню — список. Меню каждой области ищется так же, как у op/menu.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
places | footer_1,footer_2,footer_3 | области через запятую; пустые пропускаются |
lang | "" | язык меню |
class | op-footer-columns | корневой класс; колонки — __column и __column--<область>, заголовки __title, списки __list |
При пустоте: <!-- op/footer-columns: меню подвала не назначены -->. Печать на запросе: нет.
<div class="site-footer__columns"><!-- wp:op/footer-columns /--></div>
op/copyright
Строка копирайта в span. Пустой не бывает.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
text | "" | текст; {year} и {name} заменяются текущим годом и именем сайта; пусто — © <год> <имя сайта> |
class | op-copyright | класс span |
Печать на запросе: нет. В испечённой копии год застывает до следующей выпечки.
<!-- wp:op/copyright {"text":"© {year} {name}. Все права защищены."} /-->
Списки и данные
op/repeat
Повторитель печатает своё тело по разу на каждый элемент списка. Так фрейм показывает FAQ, ссылки подвала, тарифы или детей страницы. Список отдаёт один резолвер в жёстком порядке: системный источник (menu.header, site.languages, pages.children, breadcrumbs и другие), затем набор сайта с этим именем, затем инлайновый items. Источники и наборы описаны в разделе Данные.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
source | "" | имя системного источника или набора сайта |
items | [] | список прямо во вставке, если он нужен ровно в одном месте |
lang | "" | язык варианта набора; пусто — язык страницы, затем язык прогона; нет варианта — общий набор |
statuses | publish | статусы страниц для источников pages.*, через запятую |
page | 0 | страница для контекстных источников; 0 — печатаемая |
match | {} | фильтр {"поле":"токен"}: остаются элементы, у которых поле строкой равно значению токена; токены те же, что в биндах, или raw:<значение> |
empty | "" | frame — при пустом списке весь ближайший фрейм не печатается |
Внутри тела поле элемента — это item.<поле> в бинде, вложенные поля через точку: item.q, item.prev.title, item.children.0.url. Поля элемента подставляет сам повторитель для каждой копии; вне цикла у item.* значения нет, и общий проход биндов такую разметку не трогает. Настоящий фрагмент подвала сайта 235, набор footer_legal:
<nav class="site-footer__legal" aria-label="Legal">
<!-- wp:op/repeat {"source":"footer_legal"} -->
<a class="site-footer__legal-link" data-op-bind='{"text":"item.text","href":"item.url"}'></a>
<!-- /wp:op/repeat -->
</nav>
match фильтрует любой источник. Совпасть должны все пары; числа сравниваются строкой, true как "1", false как ""; массивы, объекты и отсутствующие поля не совпадают никогда; токен без значения даёт пустой список. Один набор FAQ на весь сайт, отфильтрованный по слагу страницы, и блок, спрятанный там, где вопросов нет:
<!-- wp:op/repeat {"source":"faq","match":{"page":"page.slug"},"empty":"frame"} -->
<details><summary data-op-bind='{"text":"item.q"}'></summary><div data-op-bind='{"html":"item.a"}'></div></details>
<!-- /wp:op/repeat -->
При пустоте, если empty не frame: <!-- op/repeat: список «faq» пуст -->, <!-- op/repeat: список «breadcrumbs» пуст, источник контекстный и позван без страницы -->, <!-- op/repeat: пустой шаблон элемента -->. С "empty":"frame" ближайший фрейм не печатается; вне фрейма пропадает только сам повторитель. Отчёт печати перечисляет каждый повторитель с source, origin, items, binds и unresolved, так что «список пуст» отличается от «вставка не сработала».
Печать на запросе: да, если source контекстный (pages.children, pages.siblings, pages.adjacent, breadcrumbs) или в match стоит токен page.*; иначе нет, и правка набора перепекает фрейм. Сам по себе "empty":"frame" печать на запросе не включает. Рецепт: FAQ из данных.
op/faq-schema
JSON-LD FAQPage из того же списка, что у соседнего повторителя: тот же источник, язык и match, поэтому вопросы в разметке и в аккордеоне всегда совпадают. HTML из вопросов и ответов вычищается, элементы без вопроса или ответа пропускаются.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
source | "" | источник или набор, как у op/repeat |
match | — | фильтр, как у op/repeat |
lang | "" | язык набора |
page | 0 | страница для фильтра и контекстных источников |
question | q | поле с вопросом, можно путь через точку |
answer | a | поле с ответом |
Печатает один <script type="application/ld+json">. Пустой список не печатает ничего, даже комментария. Печать на запросе: да.
<!-- wp:op/faq-schema {"source":"faq","match":{"page":"page.slug"}} /-->
Документация
Эти пять печатают части доковой раскладки темы, поэтому раздел документации собирает фрейм, а не жёсткие слоты шаблона. Все берут страницу из контекста прогона и принимают атрибут page, чтобы задать её явно.
op/docs-nav
Левое дерево доковых страниц: активный пункт, раскрытый предок, черновики для редакторов, ручки перетаскивания и кнопка «добавить дочернюю». Это шаблонная часть темы template-parts/docs-aside-left; порядок — порядок сайдбара документации.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
search | true | false убирает собственное поле поиска дерева, когда фрейм ставит op/search отдельно |
При пустоте: <!-- op/docs-nav: шаблонная часть template-parts/docs-aside-left ничего не напечатала -->. Печать на запросе: да.
<nav class="opdoc__sidebar" aria-label="Pages"><!-- wp:op/docs-nav /--></nav>
op/outline
Правое оглавление по заголовкам H2–H6 страницы, с теми же якорями, которые op/content проставляет в тексте.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
title | "" | заголовок блока; пусто — «On this page», на русской странице «На этой странице» |
bare | false | печатать только список ul, без обёртки и заголовка |
При пустоте: <!-- op/outline: страницы в контексте нет, оглавлению не по чему строиться -->, <!-- op/outline: на странице нет заголовков H2–H6 -->. Печать на запросе: да.
<div class="opdoc__aside"><!-- wp:op/outline /--></div>
op/pager
Ссылки на предыдущую и следующую страницы в том же порядке, что и в левом дереве. Пустая сторона держит распорку, чтобы «следующая» оставалась справа.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
prev_label | "" | подпись ссылки назад; пусто — ядровое «Previous» в локали страницы («Назад» по-русски) |
next_label | "" | подпись ссылки вперёд; пусто — «Next» («Далее») |
label | Documentation pages | aria-label у nav |
При пустоте: <!-- op/pager: страницы в контексте нет, соседей не у кого спрашивать -->, <!-- op/pager: у страницы нет ни предыдущей, ни следующей -->. Печать на запросе: да.
<!-- wp:op/pager /-->
op/search
Поле поиска по дереву, вынутое из той же шаблонной части, чтобы классы и иконки совпадали. Скрипт фильтрации живёт в бандле темы и работает только внутри контейнера дерева; поставленное в другом месте, это просто поле ввода.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
placeholder | Search | плейсхолдер и aria-label запасного поля |
Пустым не бывает. Печать на запросе: нет.
<!-- wp:op/docs-nav {"search":false} /-->
<!-- wp:op/search {"placeholder":"Поиск по документации"} /-->
op/share-ai
Кнопка «Copy» с выпадающим «Explore with AI»: семь ссылок на ИИ-ассистентов, собранных из адреса текущей страницы, плюс «Copy Markdown».
| Атрибут | По умолчанию | Что значит |
|---|---|---|
copy | true | false печатает только список ссылок на ассистентов — для фрейма со своей кнопкой |
label | Copy | подпись кнопки |
При пустоте: <!-- op/share-ai: шаблонная часть template-parts/aside-open-in-ai ничего не напечатала -->. Печать на запросе: да.
<div class="opdoc__copy-panel"><!-- wp:op/share-ai {"copy":false} /--></div>
Статья
op/featured-image
Картинка записи как <picture> с размерами и WebP-источниками — тем же кодом, каким печатается любая картинка сайта. Без обработчика изображений — простой <img>.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
class | "" | класс img |
picture_class | "" | класс picture |
loading | lazy | lazy или eager; для картинки на первом экране — eager |
fetchpriority | "" | high для главной картинки страницы |
link | false | обернуть в ссылку на страницу |
figure | false | обернуть в figure с подписью вложения в figcaption |
alt — альтернативный текст вложения, а если он пуст — заголовок страницы. При пустоте: <!-- op/featured-image: страницы в контексте нет -->, <!-- op/featured-image: у записи нет изображения -->, <!-- op/featured-image: файла изображения нет -->. Печать на запросе: да.
<!-- wp:op/featured-image {"loading":"eager","fetchpriority":"high","figure":true} /-->
op/terms
Термины таксономии текущей записи списком ссылок.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
taxonomy | category | таксономия: category, post_tag или любая зарегистрированная |
class | op-terms | корневой класс; ещё op-terms--<таксономия>, пункты __item--<слаг> |
link | true | false печатает имена в span без ссылок |
limit | 0 | не больше стольких терминов, 0 — все |
label | "" | подпись перед списком |
При пустоте: <!-- op/terms: страницы в контексте нет -->, <!-- op/terms: таксономии «x» на сайте нет -->, <!-- op/terms: у записи нет терминов таксономии «post_tag» -->. Печать на запросе: да. Для одной рубрики над заголовком есть ещё бинды page.category_name и page.category_url.
<!-- wp:op/terms {"taxonomy":"post_tag","label":"Метки:","limit":5} /-->
Прочее
op/callout
Врезка с настоящим вложенным телом: абзацы, списки, блоки кода. Разметка и классы — как у onpress/standard-alert, поэтому стили общие.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
variant | default | default, info, success, warning, destructive; всё прочее становится default |
icon | "" | имя символа Material Symbols; пусто — иконка варианта |
title | "" | заголовок |
showIcon | true | показывать иконку |
showTitle | true | показывать заголовок |
При пустоте: <!-- op/callout: ни заголовка, ни содержимого -->. Печать на запросе: нет. Чаще всего стоит в контенте страницы:
<!-- wp:op/callout {"variant":"warning","title":"Только одинарные кавычки"} -->
<!-- wp:paragraph -->
<p>JSON в data-op-bind держите в одинарных кавычках.</p>
<!-- /wp:paragraph -->
<!-- /wp:op/callout -->
op/assistant
Встроенный чат-ассистент Framesuite — тот же код, что у блока onpress/ai-assistant в контенте v1. Один на страницу. Плагин сам находит вставку во фрейме страницы, включая вложенные фреймы, и добавляет в <head> карту импортов и загрузчик ассистента.
| Атрибут | По умолчанию | Что значит |
|---|---|---|
id | "" | id ассистента |
assistantId | "" | псевдоним id, чтобы блок, перенесённый из контента v1, продолжал работать |
При пустоте: <!-- op/assistant: плагин onpress-blocks не активен на сайте -->. Печать на запросе: да. Настоящий фрейм лендинга сайта 235:
<section class="opland__assistant"><!-- wp:op/assistant {"id":"bDXYZ0st8QIM"} /--></section>