Block Patterns (Unsynced, Synced, Override)
В этой статье разберем паттерны в WordPress, какие бывают и как работают, поговорим об overrides в Synced Patterns, что такое contentOnly режим и при чем тут Block Bindings API.
В WordPress 6.6 появились overrides в синхронизированных паттернах. Они позволяют менять контент в отдельном экземпляре паттерна, но сохранять общую разметку и дизайн.
В WordPress 7.0 overrides стали работать и с кастомными блоками. Для этого нужные атрибуты блока должны поддерживать Block Bindings.
Введение
Паттерны в WordPress - это готовые наборы блоков, которые можно быстро вставлять в контент страниц и шаблоны. Они помогают не собирать одинаковые секции вручную каждый раз: карточки, hero-блоки, CTA, колонки, баннеры и другие повторяемые элементы.
Главная задача паттернов - ускорить сборку страниц и сохранить единый дизайн. Но на практике часто нужно больше контроля: зафиксировать структуру и стили паттерна, но оставить редактору возможность менять только нужный контент. Например, заголовок, текст, изображение или ссылку кнопки.
Например, в карточке можно разрешить менять только:
- заголовок
- описание
- текст и ссылку кнопки
А остальное останется общим:
- контейнеры
- отступы
- типографика
- классы
- структура блоков
Для этого используются две возможности:
- contentOnly - ограничивает редактирование только контентом.
- Pattern Overrides - сохраняют разные значения контента в разных экземплярах одного Synced Pattern.
Unsynced pattern (WP 7.0)
До WP 7.0. Это обычный паттерн, который вставляется в страницу как независимая копия. Изменения в одном экземпляре не влияют на другие места, где был использован этот же паттерн.
После WP 7.0 такие паттерны по умолчанию работают в contentOnly режиме. Юзер может менять только контент (текст, ссылки, изображения), но не редактирует напрямую структуру, стили, отступы, классы и настройки блоков.
Это позволяет использовать паттерн как готовую секцию сайта: редактор меняет содержимое, но не ломает дизайн.
Чтобы изменить структуру или дизайн паттерна, нужно нажать Edit pattern или дважды кликнуть по телу паттерна.


contentOnly режим в Unsynced pattern
Это режим редактирования UI/lock. Он скрывает структуру блока или паттерна, оставляя только контентные поля. Скрываются многие контролы в инспекторе.
Такая модель полезна под редакторов, которые смогут менять только контент (текст, ссылки и изображения), но не смогут изменить/сломать дизайн.
В contentOnly режиме WordPress:
- отключает контролы инспектора для настроек и стилей;
- оставляет доступными атрибуты (настройки), которые считаются контентом.
С WP 7.0 несинхронные паттерны и template parts, по умолчанию работают в contentOnly режиме (редактирования только контента).
Включаем contentOnly режим
Для этого нужно установить атрибут templateLock = contentOnly для блока.
В редакторе для этого нет отдельного UI, поэтому атрибут обычно добавляют в разметку блока вручную.
Попробуйте на демо WordPress Playground:
До и после:
Обратите внимание: все настройки в инспекторе блока исчезли. Пользователь теперь может редактировать только контент блоков Heading, Paragraph и Button.
Отключаем contentOnly режим
Настройка редактора блоков disableContentOnlyForUnsyncedPatterns позволяет отключить режим contentOnly для unsynced patterns.
Через PHP фильтр block_editor_settings_all:
add_filter(
'block_editor_settings_all',
function ( $settings ) {
$settings['disableContentOnlyForUnsyncedPatterns'] = true;
return $settings;
}
);
Через JavaScript:
wp.data.dispatch( 'core/block-editor' ).updateSettings( {
disableContentOnlyForUnsyncedPatterns: true,
} );
Когда disableContentOnlyForUnsyncedPatterns = true, блоки с metadata patternName больше не считаются section blocks, а их дочерние блоки не переводятся в режим contentOnly.
Эта настройка не затрагивает Template parts и synced patterns (core/block). Они остаются section blocks независимо от этой настройки.
Synced pattern
contentOnly режим не имеет смысла для Synced pattern, потому что тут засинковано все: лейоут, дизайн и контент.
Synced Patterns (reusable blocks), создаются в редакторе. Их разметка хранится в базе данных, а сам паттерн можно использовать на разных страницах.
Если изменить оригинальный Synced Pattern, то изменяться все места где он используется.
Видео о том, как создавать Synced Patterns:
Пользователь нажимает Edit original и попадает в отдельный редактор оригинального паттерна. Изменения оригинала применяются глобально ко всем экземплярам паттерна.


Synced pattern с overrides
Структура и дизайн остаются синхронизированными, а разрешенные значения контента можно менять отдельно в каждом экземпляре.
Рассмотрим на примере.
На изображении показана карточка, созданная как синхронный паттерн (synced pattern). Обратите внимание на тулбар блока и инспектор справа.

Обе карточки используют один и тот же паттерн, но содержат разный контент. Пользователь может менять только те части, для которых включены overrides, например заголовок, текст или ссылку кнопки.
Разметка и стили при этом остаются общими. Если изменить оригинальный паттерн, изменения применятся ко всем карточкам. Но контент останется прежний (отдельно для каждой карточки).
Пример создания overrides
Рассмотрим пример создания override synced pattern, чтобы сразу понять как это работает.
У нас есть дизайн карточки:

Пользователь должен иметь возможность менять заголовок, описание и кнопку. Все остальное должно быть зафиксировано и оставаться синхронным между экземплярами паттерна.
Нужно превратить родительский блок в synced pattern. Для этого в тулбаре блока выберите Create pattern.
В модалке задайте имя паттерна и убедитесь, что включен переключатель Synced.

Теперь в тулбаре появится фиолетовая иконка, а обводка блока станет фиолетовой вместо синей. Это означает, что контент синхронизирован.
Обратите внимание, что вы больше не можете напрямую редактировать внутренние блоки.
Они теперь редактируются на отдельном экране. Выберите Edit original в тулбаре блока, чтобы редактировать паттерн.

Дальше нужно добавить overrides к блокам Heading, Paragraph и Button. Эти блоки поддерживают нужные атрибуты Block Bindings, поэтому они также поддерживают Pattern Overrides.
Начните с Heading, откройте панель Advanced в инспекторе блока. Там будет кнопка Enable overrides.

Нажмите Enable overrides - откроется модалка.
Она попросит ввести уникальное имя override. Это нужно, чтобы WordPress мог сопоставить пользовательский контент с правильным блоком внутри паттерна.
Выберите любое имя. На изображении ниже используется "Card heading".

Повторите процесс для Paragraph и Button. Ваш паттерн будет похож на этот:

Если переключиться в Code Editor, вы увидите source для bindings у каждого блока, установленный в core/pattern-overrides. Это Block Bindings API в действии.
Пример разметки Paragraph:
<!-- wp:paragraph {
"metadata":{
"bindings":{
"__default":{"source":"core/pattern-overrides"}
},
"name":"Card Description"},
"fontSize":"small"
}
-->
<p class="has-small-font-size">Card description. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<!-- /wp:paragraph -->
__default означает, что источник core/pattern-overrides применяется к поддерживаемым атрибутам блока по умолчанию. Для Paragraph это content, для Button это несколько атрибутов: text, url, linkTarget, rel.
Если нужно сделать разметку более явной, можно указать конкретный атрибут:
<!-- wp:paragraph {
"fontSize":"small"
"metadata":{
"bindings":{
"content":{"source":"core/pattern-overrides"}
},
"name":"Card Description"
}
} -->
<p class="has-small-font-size">Card description.</p>
<!-- /wp:paragraph -->
Сохраните паттерн и вернитесь к записи, где размещен паттерн. Вставьте тот же паттерн во вторую колонку и измените заголовки, чтобы увидеть работу overrides.

Далее измените сам synced pattern, чтобы увидеть, как он обновляет каждый экземпляр, сохраняя при этом ваши контентные изменения. Попробуйте добавить дополнительные overrides, например, изображение сверху карточки.
Видео:
https://videopress.com/embed/hhD0510P?cover=1&autoPlay=0&controls=1&loop=1&muted=0&persistVolume=1&playsinline=0&preloadContent=metadata&useAverageColor=1&hd=0Атрибуты контента в block.json
При создании своих блоков с WP 7.0 им можно обозначить какие из атрибутов считать контентными.
attributes: role: content
Точечно помечает конкретные атрибуты как контент, когда блок должен быть редактируемым внутри contentOnly паттерна. Контентные атрибуты блока нужно разметить как role: content.
{
"attributes": {
"url": {
"type": "string",
"role": "content"
},
"label": {
"type": "string",
"role": "content"
}
}
}
Если у блока нет атрибутов с role: content, он может быть скрыт из List View и стать недоступным для выбора внутри contentOnly контейнера.
contentRole
Помечает весь блок как контентный блок. Это нужно, когда у блока нет подходящего атрибута, который можно поменить как контентный.
Включаем поддержку contentRole:
{
"supports": {
"contentRole": true
}
}
Такой вариант нужен в основном для составных блоков, где редактируемый контент находится не в атрибутах самого блока, а во внутренних блоках (InnerBlocks).
В contentOnly режиме такой блок не будет восприниматься как пустая техническая обертка. Он останется доступным для выбора и редактирования, а его внутренние блоки можно будет менять в рамках ограничений contentOnly.
Block Bindings API
Overrides появились в WordPress 6.6, потому что для них нужен механизм привязки пользовательских значений к атрибутам блоков внутри паттерна. Эту задачу решает Block Bindings API.
Block Bindings API позволяет связывать атрибуты блоков с разными источниками данных:
- кастомные поля записи;
- данные записи;
- данные термина;
- данные сайта;
- пользовательские источники;
- значения overrides внутри паттерна.
Для Pattern Overrides используется встроенный источник core/pattern-overrides.
Чтобы использовать overrides, не обязательно глубоко знать весь Block Bindings API. Но важно понимать базовую связь: override - это не отдельная система хранения внутри блока, а binding (связь) атрибута блока с источником core/pattern-overrides.
Посмотрим простой пример.

Предположим, вы хотите привязать метаполя поста к блокам Heading, Paragraph и Button, чтобы значения хранились/брались не из разметки блока, а из метаполей записи.
Сначала через register_meta() регистрируем метаполя для каждого атрибута блока. Назовем их: card_heading, card_description, card_button_text, card_button_url:
add_action( 'init', 'theme_slug_register_meta' );
function theme_slug_register_meta(): void {
register_meta(
'post',
'card_heading',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'sanitize_callback' => 'wp_strip_all_tags',
'default' => 'Card heading',
)
);
register_meta(
'post',
'card_description',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'sanitize_callback' => 'wp_strip_all_tags',
'default' => 'Card description. Lorem ipsum dolor sit amet.',
)
);
register_meta(
'post',
'card_button_text',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'sanitize_callback' => 'wp_strip_all_tags',
'default' => 'Learn more',
)
);
register_meta(
'post',
'card_button_url',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'sanitize_callback' => 'esc_url_raw',
'default' => 'https://wordpress.org',
)
);
}
Этот код регистрирует метаполя и делает их доступными в REST API. Важный параметр - show_in_rest = true.
Далее привяжем метаданные к блокам через атрибут metadata. Например, для Heading это выглядит так:
"metadata": {
"bindings": {
"content": {
"source": "core/post-meta",
"args": {
"key": "card_heading"
}
}
}
}
Где:
metadata- объект с метаданными блока.bindings- объект с одной или несколькими привязками.content- атрибут блока, который привязывается к источнику.source- источник данных. Для метаполей этоcore/post-meta.args- аргументы источника. Для метаполя укажитеkey.
Пока не все bindings удобно настраиваются через UI, поэтому разметку часто правят вручную через Code Editor.
Полная разметка Heading будет такой:
<!-- wp:heading {
"metadata":{
"bindings":{
"content":{
"source":"core/post-meta",
"args":{"key":"card_heading"}
}
}
}
} -->
<h2 class="wp-block-heading">Card heading</h2>
<!-- /wp:heading -->
Обратите внимание: привязка нацелена на content - это атрибут content у Heading. Аналогично можно привязать Paragraph и Button.
Поддерживаемые core блоки и атрибуты
В WP 7.0 Pattern Overrides можно включить и для кастомных блоков, если добавить нужные атрибуты в список поддерживаемых через фильтр block_bindings_supported_attributes.
Базовый список поддерживаемых атрибутов Core-блоков:
| Блок | Атрибуты |
|---|---|
core/image |
id, url, title, alt, caption |
core/heading |
content |
core/paragraph |
content |
core/button |
url, text, linkTarget, rel |
core/navigation-link |
url |
core/navigation-submenu |
url |
core/post-date |
datetime |
Поскольку Pattern Overrides работают через Block Bindings, доступность overrides определяется этим же списком поддерживаемых атрибутов.
Скриншот ниже показывает дизайн карточки, где каждый блок привязан к зарегистрированным кастомным полям. Визуально все похоже из-за дефолтного контента, но обратите внимание на новое значение card_heading и панель Bindings в инспекторе блока.

Подробнее про Block Bindings API:
- https://developer.wordpress.org/news/2024/02/20/introducing-block-bindings-part-1-connecting-custom-fields/
- https://developer.wordpress.org/news/2024/03/06/introducing-block-bindings-part-2-working-with-custom-binding-sources/
- https://developer.wordpress.org/block-editor/reference-guides/block-api/block-bindings/
Как Pattern Overrides хранят значения
Когда атрибут блока привязан к core/pattern-overrides, WordPress использует имя блока из metadata.name как ключ для хранения значения.
Пример блока внутри оригинального паттерна:
<!-- wp:paragraph {
"metadata":{
"name":"card-description"
"bindings":{ content":{ source":"core/pattern-overrides" } }
}
} -->
<p>Card description</p>
<!-- /wp:paragraph -->
Где:
metadata.name- уникальный ключ override внутри паттерна.content- атрибут блока, который можно переопределить.core/pattern-overrides- источник данных, из которого будет взято значение для конкретного экземпляра паттерна.
Когда паттерн вставлен как Synced Pattern, экземпляр хранит локальные значения overrides в атрибуте content блока core/block:
<!-- wp:block {
"ref":123,
"content":{
"card-description":{
"content":"Описание только для этой карточки"
}
}
} /-->
То есть оригинальный паттерн остается общим, а локальное значение хранится в месте вставки паттерна.
Pattern Overrides для кастомных блоков
В WordPress 7.0 overrides можно указывать и для кастомных блоков: любой атрибут, который поддерживает Block Bindings, также может использовать Pattern Overrides.
В WordPress 6.6 overrides работали только с ограниченным набором Core-блоков и атрибутов.
Для кастомного блока нужно сделать две вещи:
- описать атрибуты блока в
block.json; - добавить нужные атрибуты в список поддерживаемых Block Bindings через фильтр.
Пример кастомного блока
Допустим, есть блок my-plugin/cta-card. У него есть заголовок, текст, URL кнопки и текст кнопки.
Фрагмент block.json:
{
"apiVersion": 3,
"name": "my-plugin/cta-card",
"title": "CTA Card",
"category": "widgets",
"attributes": {
"title": {
"type": "string",
"source": "html",
"selector": ".my-cta-card__title",
"role": "content"
},
"text": {
"type": "string",
"source": "html",
"selector": ".my-cta-card__text",
"role": "content"
},
"url": {
"type": "string",
"source": "attribute",
"selector": ".my-cta-card__link",
"attribute": "href",
"role": "content"
},
"linkText": {
"type": "string",
"source": "html",
"selector": ".my-cta-card__link",
"role": "content"
}
}
}
role: content нужен для нормальной работы блока в contentOnly режиме. Но сам по себе он не включает Block Bindings. Для bindings нужен фильтр.
Подключение атрибутов через фильтр
Вариант через динамический фильтр конкретного блока:
add_filter( 'block_bindings_supported_attributes_' . 'my-plugin/cta-card', 'theme_cta_card_supported_binding_attrs' );
function theme_card_supported_binding_attrs( array $attrs ): array {
return [ ...$attrs, 'title', 'text', 'url', 'linkText' ];
}
Вариант через общий фильтр:
add_filter( 'block_bindings_supported_attributes', 'theme_card_supported_binding_attrs', 10, 2 );
function theme_card_supported_binding_attrs( array $attrs, string $block_type ): array {
if ( 'my-plugin/cta-card' !== $block_type ) {
return $attrs;
}
return array_merge( attrs, [ 'title', 'text', 'url', 'linkText' ] );
}
После этого атрибуты title, text, url и linkText становятся доступными для Block Bindings. А в WordPress 7.0 они также могут быть использованы как Pattern Overrides.
Разметка паттерна с кастомным блоком
В оригинальном Synced Pattern можно привязать атрибуты своего блока к core/pattern-overrides.
<!-- wp:my-plugin/cta-card {
"metadata":{
"name":"cta-card",
"bindings":{
"title":{"source":"core/pattern-overrides"},
"text":{"source":"core/pattern-overrides"},
"url":{"source":"core/pattern-overrides"},
"linkText":{"source":"core/pattern-overrides"}
}
}
} -->
<div class="wp-block-my-plugin-cta-card my-cta-card">
<h2 class="my-cta-card__title">Default title</h2>
<p class="my-cta-card__text">Default text.</p>
<a class="my-cta-card__link" href="https://example.com">Default link</a>
</div>
<!-- /wp:my-plugin/cta-card -->
Теперь каждый экземпляр Synced Pattern сможет хранить свои значения этих атрибутов, а оригинальный паттерн продолжит управлять структурой и дизайном.
Имена в metadata.name должны быть уникальными внутри паттерна. Если два блока внутри одного паттерна используют одно и то же имя, WordPress не сможет надежно сопоставить override с нужным блоком.
Динамические блоки
Для динамического блока bindings значения атрибутов будут переданы в параметр $attributes коллбэк функции render_callback. См. register_block_type():
add_action( 'init', 'theme_register_cta_card_block' );
function theme_register_cta_card_block(): void {
register_block_type(
__DIR__ . '/build/cta-card',
[
'render_callback' => 'theme_render_cta_card_block',
]
);
}
function theme_render_cta_card_block( array $attributes ): string {
$title = $attributes['title'] ?? '';
$text = $attributes['text'] ?? '';
$url = $attributes['url'] ?? '';
$link_text = $attributes['linkText'] ?? '';
ob_start();
?>
<div <?php echo get_block_wrapper_attributes( array( 'class' => 'my-cta-card' ) ); ?>>
<?php if ( $title ) : ?>
<h2 class="my-cta-card__title"><?php echo esc_html( $title ); ?></h2>
<?php endif; ?>
<?php if ( $text ) : ?>
<p class="my-cta-card__text"><?php echo esc_html( $text ); ?></p>
<?php endif; ?>
<?php if ( $url && $link_text ) : ?>
<a class="my-cta-card__link" href="<?php echo esc_url( $url ); ?>"><?php echo esc_html( $link_text ); ?></a>
<?php endif; ?>
</div>
<?php
return (string) ob_get_clean();
}
Блок сам отвечает за финальную HTML-разметку.
Статические блоки
Для статических блоков WordPress пытается применить связанные значения к сохраненной HTML-разметке через HTML API.
Это работает, когда атрибуты имеют понятный источник:
htmlrich-textattribute
И когда селекторы достаточно простые, чтобы HTML API мог найти нужный элемент в сохраненной разметке.
Например, это хороший случай:
"title": {
"type": "string",
"source": "html",
"selector": ".my-cta-card__title"
}
И это тоже хороший случай:
"url": {
"type": "string",
"source": "attribute",
"selector": ".my-cta-card__link",
"attribute": "href"
}
Сложнее, если атрибут:
- не имеет
source; - собирается из нескольких элементов;
- использует сложный selector;
- влияет не на текст или HTML-атрибут, а на нестандартную часть разметки;
- требует дополнительной логики перед выводом.
В таких случаях лучше сделать блок динамическим или обработать вывод через фильтр render_block.
Сначала попробуйте только добавить атрибуты через block_bindings_supported_attributes. Если значения корректно появляются на фронтенде, дополнительный render callback не нужен. Если значение есть в редакторе, но не попадает в HTML на фронтенде, добавьте серверный рендеринг.
Итерации Block Bindings API
В последних версиях WordPress Block Bindings API стал удобнее для редакторского интерфейса.
Для источников bindings можно регистрировать список доступных полей через getFieldsList. Это нужно, чтобы редактор мог показать пользователю понятный список полей и скрыть несовместимые варианты.
getFieldsList возвращает массив объектов:
label- подпись поля в интерфейсе.type- тип значения. Он должен совпадать с типом атрибута блока.args- аргументы, которые будут переданы источнику после выбора поля.
Пример регистрации источника в редакторе:
wp.blocks.registerBlockBindingsSource( {
name: 'theme-slug/labels',
label: 'Labels',
getValues( { bindings } ) {
if ( bindings.content?.args?.key === 'first' ) {
return { content: 'First label' };
}
if ( bindings.content?.args?.key === 'second' ) {
return { content: 'Second label' };
}
return { content: '' };
},
getFieldsList() {
return [
{
label: 'First label',
type: 'string',
args: {
key: 'first',
},
},
{
label: 'Second label',
type: 'string',
args: {
key: 'second',
},
},
];
},
} );
Если атрибут блока имеет тип string, редактор покажет только поля с type: 'string'. Если атрибут ожидает число, строковые поля не будут предложены.
Это особенно важно для кастомных источников данных, где один источник может отдавать поля разных типов.
Ограничения
После WordPress 7.0 ограничений стало меньше, но они все еще есть:
- Статические блоки зависят от того, сможет ли HTML API найти и заменить значение в сохраненной разметке.
- Synced Patterns по-прежнему хранятся в базе данных и не могут быть полноценно упакованы как обычные pattern-файлы темы.
- Overrides не предназначены для изменения структуры паттерна. Они переопределяют значения атрибутов, а не набор вложенных блоков.
Дополнительно по теме
- https://make.wordpress.org/core/2026/03/16/pattern-overrides-in-wp-7-0-support-for-custom-blocks/
- https://make.wordpress.org/core/2026/03/15/pattern-editing-in-wordpress-7-0/
- https://developer.wordpress.org/block-editor/reference-guides/block-api/block-bindings/
Подробнее:
- https://make.wordpress.org/core/2026/03/16/pattern-overrides-in-wp-7-0-support-for-custom-blocks/
- https://make.wordpress.org/core/2026/03/15/pattern-editing-in-wordpress-7-0/
- https://developer.wordpress.org/block-editor/reference-guides/block-api/block-bindings/
Developer Hours от 11 июня 2024, запись доступна на WordPress.tv:
https://wordpress.tv/2024/06/11/developer-hours-exploring-synced-pattern-overrides-in-wordpress-6-6/

