PHP-only block registration: блоки без JavaScript
С версии WordPress 7.0 блок можно зарегистрировать одним PHP-вызовом — без block.json, без сборки JavaScript и без registerBlockType на клиенте. Флаг supports.autoRegister включает режим, в котором ядро само создаёт запись блока в редакторе и само рисует контролы атрибутов в боковой панели. Такой блок всегда рендерится на сервере через render_callback.
Подход рассчитан на серверные блоки: вывод связанных записей, виджет-подобные настройки, блоки темы, которые раньше делали шорткодом. Он не заменяет клиентскую модель блоков и никогда не сравнится с ней по возможностям — интерактивные блоки по-прежнему пишутся на JavaScript.
Минимальный блок
Заголовок раздела «Минимальный блок»register_block_type получает имя блока и массив настроек. Обязательны два элемента: render_callback и supports.autoRegister => true.
add_action( 'init', 'myplugin_register_blocks' );
function myplugin_register_blocks() { register_block_type( 'myplugin/notice', array( 'title' => __( 'Notice', 'myplugin' ), 'category' => 'design', 'attributes' => array( 'text' => array( 'label' => __( 'Текст', 'myplugin' ), 'type' => 'string', 'default' => __( 'Обратите внимание', 'myplugin' ), ), 'level' => array( 'label' => __( 'Уровень', 'myplugin' ), 'type' => 'string', 'enum' => array( 'info', 'warning', 'error' ), 'default' => 'info', ), ), 'render_callback' => 'myplugin_render_notice', 'supports' => array( 'autoRegister' => true, 'html' => false, ), ) );}
function myplugin_render_notice( $attributes ) { $level = in_array( $attributes['level'], array( 'info', 'warning', 'error' ), true ) ? $attributes['level'] : 'info';
return sprintf( '<div %1$s><p class="notice notice--%2$s">%3$s</p></div>', get_block_wrapper_attributes(), esc_attr( $level ), esc_html( $attributes['text'] ) );}Что здесь важно:
render_callbackобязателен. Без него блок не отрисуется: у PHP-only блока нет сохранённой разметки, только серверный рендер.get_block_wrapper_attributes()отдаёт классы и стили, которые редактор ждёт на обёртке блока. Без него поддержка цветов, отступов, типографики и пользовательские классы не применятся, хотя самиsupportsформально включены.supports.html: falseубирает вкладку «Дополнительно → HTML-элемент», которая для серверного блока бессмысленна.
Какие контролы генерируются
Заголовок раздела «Какие контролы генерируются»Ядро строит контрол по типу атрибута:
| Тип атрибута | Контрол в боковой панели |
|---|---|
string | текстовое поле |
string + enum | выпадающий список |
number, integer | числовое поле |
boolean | переключатель |
Это весь поддерживаемый набор на 7.0. Медиафайлы, rich text, многострочный текст, дата и цвет как отдельные поля не поддерживаются.
Дополнительные правила:
labelпереводим. Подпись контрола берётся из атрибутаlabelи оборачивается в__()— без него в панели будет техническое имя атрибута.- Только несурced-атрибуты. Атрибут должен сохраняться в JSON-комментарии блока, а не извлекаться из HTML (
source). Для sourced-атрибутов контрол не создаётся. role: local— без контрола. Атрибуты с рольюlocalне сохраняются в контенте (это состояние редактора), поэтому панель их не показывает.enumбез пар «ключ → подпись». В списке выводятся сами значения (info,warning), локализовать их нельзя. Если нужны человеческие подписи — выносите выбор в отдельный атрибут сenumиз чисел и маппинг в PHP-рендере.
Ограничения, о которых стоит знать заранее
Заголовок раздела «Ограничения, о которых стоит знать заранее»Нет save. Блок не хранит свою разметку в post_content — только атрибуты. Сохранить HTML на этапе редактирования (как у статических блоков) нельзя, и в ядре не планируют это добавлять: пришлось бы решать задачу надёжного извлечения атрибутов из HTML.
Нет внутренних блоков. InnerBlocks в PHP-only блоках недоступен. Контейнер с вложенными колонками или группами так не собрать — для этого нужен обычный клиентский блок. Практический потолок подхода — «серверный виджет»: один блок, несколько настроек, готовый вывод.
Каждое изменение — поход на сервер. Правка атрибута вызывает повторный рендер через REST. Для блока, который тянет тяжёлый запрос, это заметно замедляет редактор: кэшируйте выборку и не запускайте дорогие запросы в render_callback без нужды.
Контекст поста при повторном рендере. uses_context с postId заполняется при первом рендере, но не при последующих вызовах из редактора через REST (тикет #65331, перенесён в Gutenberg #78619). Если блоку нужен ID записи — передавайте его атрибутом или получайте иначе, не полагайтесь на контекст.
Версия важна. Флаг появился в 7.0 (первое рабочее состояние — 7.0-beta3). На более старом ядре неизвестный ключ в supports игнорируется молча, и блок просто не появится в редакторе. Проверяйте версию явно:
if ( version_compare( get_bloginfo( 'version' ), '7.0', '<' ) ) { return; // на старом ядре блок регистрируем старым способом}Публичной функции вида current_theme_supports() для проверки autoRegister нет — остаётся сверка версии.
Когда подход уместен
Заголовок раздела «Когда подход уместен»- Классические темы. Блок даёт нормальные контролы вместо шорткода: пользователь видит настройки в панели, а не атрибуты в квадратных скобках.
- Серверные данные. Вывод последних записей, курса валют, списка услуг из настроек — то, что бессмысленно хранить в контенте.
- Блоки темы под один проект. Авторская подпись, CTA-секция, блок с фиксированной вёрсткой и парой настроек.
- Миграция шорткодов. Быстрый путь перевести шорткод в блок, не поднимая сборку JS.
Не подходит для интерактивных блоков (табы, слайдеры, аккордеоны с состоянием в редакторе), для контейнеров с вложенностью и для блоков, где важна мгновенная реакция интерфейса без обращения к серверу.
Что проверить после регистрации
Заголовок раздела «Что проверить после регистрации»- Блок виден в инсертере и вставляет нужную разметку на фронте.
- Контролы появились в боковой панели, подписи переведены.
- Стили из
supports(цвет, отступы, ширина) применяются к обёртке. - Повторное открытие записи сохраняет значения атрибутов.
- Рендер не делает тяжёлых запросов: откройте запись в редакторе и посмотрите время ответа REST-запроса блока.
Связанные страницы
Заголовок раздела «Связанные страницы»- Блочный редактор WordPress: добавление контента блоками
- Блок Custom HTML
- Паттерны (Block Patterns) — статичные композиции блоков без серверного рендера
- PHP в паттернах — где выполняется PHP в паттернах и почему это не то же самое