• Как устроено
  • Быстрый старт
  • Доступ и токен
    • Страницы
      • 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
      • Медиа
      • Сайты
      • Пользователи и профиль
      • Вход и служебное
    • Ошибки и проблемы
      • Коды ошибок
OnPress OnPress
  • Документация
  • Контакты
Войти
  • Как устроено
  • Быстрый старт
  • Доступ и токен
    • Страницы
      • 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
      • Медиа
      • Сайты
      • Пользователи и профиль
      • Вход и служебное
    • Ошибки и проблемы
      • Коды ошибок
Наборы данных и системные источники
Markdown
Открыть в ИИ
  • Открыть в ChatGPT
  • Открыть в Claude
  • Открыть в Gemini
  • Открыть в Perplexity
  • Открыть в Grok
  • Открыть в DeepSeek

Повторитель onpress/repeat

onpress/repeat — парная вставка: разметка между открытием и закрытием повторяется по разу на элемент списка, а бинды item.* внутри подставляют поля элемента.

<section class="article__faq">
  <h2>Частые вопросы</h2>
  <!-- onpress/repeat {"source":"faq","match":{"page":"page.slug"},"empty":"frame"} -->
  <details>
    <summary data-op-bind='{"text":"item.q"}'></summary>
    <p data-op-bind='{"text":"item.a"}'></p>
  </details>
  <!-- /onpress/repeat -->
</section>

Откуда берётся список

source — имя. Разрешается в таком порядке: системный источник (menu.*, site.*, pages.*, breadcrumbs, slot.faq) → набор сайта с этим именем → список items из атрибута. Во вложенном повторителе source вида item.<поле> берёт вложенный список из элемента внешнего.

<!-- набор сайта -->
<!-- onpress/repeat {"source":"tariffs"} --> … <!-- /onpress/repeat -->

<!-- системный источник: дочерние страницы текущей -->
<!-- onpress/repeat {"source":"pages.children"} --> … <!-- /onpress/repeat -->

<!-- список прямо во вставке -->
<!-- onpress/repeat {"items":[{"t":"Быстро","d":"Страница за один запрос"},{"t":"Надёжно","d":"Всё в одной транзакции"}]} -->
<li><b data-op-bind='{"text":"item.t"}'></b> <span data-op-bind='{"text":"item.d"}'></span></li>
<!-- /onpress/repeat -->

Какие поля есть у элементов системных источников — в наборах данных. У набора — какие положили (посмотреть: GET /data/{name}, поле fields).

Атрибуты

АтрибутПо умолчаниюСмысл
source—имя источника, набора или item.<поле>
items[]список в атрибуте, если source не задан или ничего не нашёл
langязык страницывариант набора; без варианта — общий набор, затем вариант основного языка
match{}фильтр элементов
limit—сколько элементов вывести
offset—сколько пропустить с начала
empty—frame — при пустом списке погасить весь фрейм
separator—строка между элементами; после последнего не ставится
statusespublishстатусы страниц для pages.* через запятую
pageстраница сборкиid страницы, от которой считать контекстные источники и page.*

Фильтр match

match оставляет элементы, у которых каждое указанное поле совпадает со значением токена:

<!-- вопросы именно этой страницы из общего набора -->
<!-- onpress/repeat {"source":"faq","match":{"page":"page.slug"}} --> … <!-- /onpress/repeat -->

<!-- страницы верхнего уровня текущего языка -->
<!-- onpress/repeat {"source":"pages.top","match":{"lang":"site.lang"}} --> … <!-- /onpress/repeat -->

<!-- три раздела по фрейму: массив — «любое из» -->
<!-- onpress/repeat {"source":"pages.top","match":{"lang":"site.lang","frame.slug":["raw:docs","raw:news","raw:pricing"]}} --> … <!-- /onpress/repeat -->
  • Ключ — поле элемента; вложенное поле — через точку (frame.slug, meta.lang).
  • Значение — токен бинда (page.slug, page.id, page.parent_id, page.data.<ключ> из frontmatter, site.lang, option.<имя>, item.<поле> во вложенном повторителе) или константа raw:<значение>.
  • Сравнение — строгое равенство строк: число сравнивается своей строкой (3 равно "3"), true — как "1", false — как пустая строка; массивы, объекты, null и отсутствующие поля не совпадают никогда.
  • Все поля — через И. Массив токенов в одном поле — через ИЛИ.
  • Токен без значения (page.parent_id у страницы верхнего уровня) делает список пустым. В массиве альтернатива без значения просто выпадает; пустым список станет, только если не разрешилась ни одна.

match с токеном page.* делает фрейм зависимым от страницы — у каждой страницы свой список.

Окно: limit и offset

<!-- три последних новости -->
<!-- onpress/repeat {"source":"news","limit":3} --> … <!-- /onpress/repeat -->

<!-- по три на страницу: ?blog_page=1 — 1–3, ?blog_page=2 — 4–6 -->
<!-- onpress/repeat {"source":"news","limit":3,"offset":"(page.paged - 1) * 3","empty":"frame"} --> … <!-- /onpress/repeat -->
  • Порядок: сначала match, потом offset, потом limit — окно режется из уже отфильтрованного списка.
  • Значение — целое или выражение из целых, токенов и + - * ( ). 3, "3" и "(2 + 1)" — одно и то же.
  • Мусор ничего не ломает: нецелое значение, отрицательный offset, limit ноль или меньше означают «атрибут не задан». offset за концом списка даёт пустой список.
  • page.paged — номер страницы из адреса, параметр ?blog_page=N (тот же, что у ленты блога темы), без параметра — 1.

Окно из чисел фрейм от страницы не зависит. Окно с page.* — зависит. Проверить окно заранее можно через GET /data/{name}?limit=3&offset=3 или POST /data/resolve с paged — ответ несёт window (что применено) и window_total (сколько было до среза).

Ссылки «следующая страница» повторитель не рисует — поставьте их разметкой: <a href="?blog_page=2">Дальше</a>.

Пустой список

Без empty пустой список оставляет на месте повторителя комментарий с пометкой op/repeat: список «faq» пуст, а окружающая разметка (заголовок секции) остаётся.

"empty":"frame" гасит весь фрейм, в котором стоит повторитель: вместо него — пустая строка. Поэтому блок с заголовком выносят в отдельный фрейм и вкладывают его в оболочку:

<!-- article -->
<main class="article">
  <!-- onpress/content /-->
  <!-- onpress/frame {"name":"article__faq"} /-->
</main>

<!-- article__faq -->
<section class="article__faq">
  <h2>Частые вопросы</h2>
  <!-- onpress/repeat {"source":"faq","match":{"page":"page.slug"},"empty":"frame"} -->
  <details><summary data-op-bind='{"text":"item.q"}'></summary><p data-op-bind='{"text":"item.a"}'></p></details>
  <!-- /onpress/repeat -->
</section>

На странице без вопросов на месте article__faq ничего нет — ни заголовка, ни пустой секции, а article выводится как обычно. Гаснет ровно один фрейм — тот, где стоит повторитель. Не ставьте "empty":"frame" в собственный фрейм страницы: погаснет вся страница. В теле страницы (вне фрейма) повторитель при пустом списке прячет только себя.

Разделитель

separator ставит строку между элементами, после последнего — нет. Нужен там, где повторитель собирает не HTML, а текст с синтаксисом: JSON, список через запятую.

<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[<!-- onpress/repeat {"source":"slot.faq","separator":","} -->{"@type":"Question","name":<!-- onpress/value {"bind":"item.q_text","format":"json"} /-->,"acceptedAnswer":{"@type":"Answer","text":<!-- onpress/value {"bind":"item.a_text","format":"json"} /-->}}<!-- /onpress/repeat -->]}</script>

Значения внутри <script> выводит onpress/value с "format":"json" — тегов для data-op-bind там нет.

Источник slot.faq

Внутри фрейма, вызванного парной формой со слотом, slot.faq отдаёт пары вопрос-ответ из содержимого вызова: уровень первого заголовка — вопрос, всё до следующего такого же — ответ. Поля элемента: q и a — HTML, q_text и a_text — текст без разметки, question и answer — исходный markdown. Готовый фрейм — в рецепте FAQ.

Вложенный повторитель

Внутренний повторитель берёт список из элемента внешнего: source вида item.<поле>.

<!-- разделы текущего языка, у каждого — две первые дочерние страницы -->
<ul class="sections">
  <!-- onpress/repeat {"source":"pages.tree","match":{"slug":["raw:docs","raw:primery"],"lang":"site.lang"}} -->
  <li>
    <a data-op-bind='{"href":"item.url","text":"item.title"}'></a>
    <ol>
      <!-- onpress/repeat {"source":"item.children","limit":2} -->
      <li><a data-op-bind='{"href":"item.url","text":"item.title"}'></a></li>
      <!-- /onpress/repeat -->
    </ol>
  </li>
  <!-- /onpress/repeat -->
</ul>

Внутри вложенного повторителя item.* — его собственный элемент. В match вложенного повторителя item.<поле> означает элемент внешнего: в момент фильтрации своего элемента ещё нет. Поле, которое не массив, даёт пустой список. item.<поле> сам по себе фрейм от страницы не делает зависимым.

Язык

Язык набора выбирается так: атрибут lang → язык страницы → язык сборки. Для меню и страниц язык влияет на то, какое меню и какие адреса придут; pages.all и pages.top по языку не фильтруются — фильтруйте match по site.lang.

Примеры

Карточки дочерних страниц раздела (в теле страницы-раздела или в её фрейме):

<!-- wp:html -->
<div class="cards">
<!-- onpress/repeat {"source":"pages.children"} -->
<a class="cards__card" data-op-bind='{"href":"item.url"}'><span data-op-bind='{"text":"item.title"}'></span></a>
<!-- /onpress/repeat -->
</div>
<!-- /wp:html -->

Своё меню из системного источника (когда разметка onpress/menu не подходит):

<nav class="topnav">
  <!-- onpress/repeat {"source":"menu.header"} -->
  <a class="topnav__link" data-op-bind='{"href":"item.url","text":"item.title","target":"item.target"}'></a>
  <!-- /onpress/repeat -->
</nav>

Хлебные крошки:

<nav class="crumbs">
  <!-- onpress/repeat {"source":"breadcrumbs"} -->
  <a data-op-bind='{"href":"item.url","text":"item.title","aria-current":"item.current"}'></a>
  <!-- /onpress/repeat -->
</nav>

Список языков сайта:

<!-- onpress/repeat {"source":"site.languages"} -->
<a data-op-bind='{"href":"item.url","text":"item.name","hreflang":"item.slug"}'></a>
<!-- /onpress/repeat -->

Поля элемента site.languages смотрите запросом GET /data/site.languages — берите их имена оттуда.

Отладка

  • POST /data/resolve с теми же source, match, page, lang, limit, offset показывает, что получит повторитель.
  • В ответе записи фрейма bake.response.repeats — что вывел каждый повторитель при пробной сборке: источник, откуда взят (origin), сколько элементов, подставленные бинды, unresolved.
  • На странице пустой список оставляет комментарий с пометкой op/repeat: список «…» пуст; у контекстного источника без страницы — с пометкой, что источник контекстный.
arrow_backНазад
Наборы данных и системные источники
Далееarrow_forward
Стили и оформление
На этой странице
  • Откуда берётся список
    • Атрибуты
      • Фильтр match
        • Окно: limit и offset
          • Пустой список
            • Разделитель
              • Источник slot.faq
                • Вложенный повторитель
                  • Язык
                    • Примеры
                      • Отладка
                      OnPress
                      OnPress
                      ИП Зуев И.В. ИНН: 360408359441
                      © 2026
                      политика конфиденциальности публичная оферта
                      • visa
                      • mastercard
                      • sber
                      • tpay