Блог

Создавайте пользовательские блоки только на PHP. Прощайте, шорткоды 🥳

David Wang
Автор: David Wang ·

Создание блоков Gutenberg требовало React, Node.js и конвейера сборки с тех пор, как WordPress 5.0 представил редактор блоков. Если ваши навыки связаны с PHP — как у меня и большинства разработчиков WordPress — этот барьер держал вас в стороне почти десятилетие. WordPress 7.0 меняет это. Блоки только на PHP позволяют зарегистрировать полностью функциональный блок Gutenberg с помощью одного PHP-файла и флага autoRegister.

Вы пишете PHP. Вы получаете блок. Никаких инструментов. Никакой сборки. 🥳 В этой статье вы узнаете, как работают блоки только на PHP, и рассмотрите реальный пример замены классического шорткода его блочным эквивалентом.

Что такое блоки только на PHP?

До сих пор создание пользовательского блока Gutenberg означало настройку инструментальной цепочки JavaScript: npm install, файл block.json, шаг сборки с webpack.config.js или @wordpress/scripts и компонент edit.js, написанный на JSX. Каждое изменение требовало шага компиляции, прежде чем вы могли увидеть его в редакторе. Для PHP-разработчика, который просто хочет зарегистрировать простой блок отображения, эти накладные расходы всегда казались несоразмерными задаче.

Блоки только на PHP устраняют всё это. Теперь в register_block_type() достаточно передать 'autoRegister' => true, и WordPress автоматически обработает всё на стороне JavaScript с помощью ServerSideRender. Блок появляется в инсерторе, отображает живой предварительный просмотр на холсте и генерирует элементы управления инспектора на боковой панели — всё это без единой строки JavaScript с вашей стороны.

Элементы управления генерируются автоматически на основе типа атрибута:

Тип атрибутаГенерируемый элемент управления инспектора
stringТекстовое поле
integer / numberЧисловое поле
booleanПереключатель
string + enumВыпадающий список

Автоматически генерируемые элементы управления пока охватывают только четыре вышеуказанных типа. Всё более сложное — например, выбор изображений, загрузка медиафайлов или вложенные данные — пока не поддерживается и потребует блока, зарегистрированного с JavaScript. Разработчики также могут помечать отдельные атрибуты ролью local, чтобы обозначить их как внутреннее состояние; WordPress пропускает их при формировании элементов управления боковой панели.

Блоки только на PHP доступны уже сегодня в WordPress 7.0 без каких-либо дополнительных зависимостей. Подробнее читайте в официальной заметке для разработчиков на Make WordPress Core.

Для кого это?

Небольшие агентства и фрилансеры без глубокой экспертизы в JavaScript теперь могут создавать решения для редактора блоков, полностью использующие нативные возможности WordPress, не касаясь конвейера сборки. Если вы хотите создавать специфичные для темы пользовательские блоки Gutenberg — такие как блоки автора, выделенные цитаты, отзывы, баннеры CTA, уведомления и подобные элементы — вместо того чтобы прибегать к шорткодам, блоки только на PHP значительно снижают этот барьер.

Они не являются заменой блоков, зарегистрированных с JavaScript, когда вам нужно встроенное редактирование форматированного текста, реактивный пользовательский интерфейс в реальном времени или вложенные блоки — но для широкого класса структурированных блоков отображения они попадают в точку.

Старый способ: шорткоды

До блоков только на PHP практическим подходом для PHP-разработчика был шорткод. Вот простой шорткод отзыва с тремя атрибутами: имя автора, компания, звёздный рейтинг, плюс внутренний контент для текста отзыва:

function testimonial_shortcode( $atts, $content = '' ) {
    $atts = shortcode_atts( [
        'name'    => '',
        'company' => '',
        'stars'   => 5,
    ], $atts );
 
    $stars_count = max( 1, min( 5, intval( $atts['stars'] ) ) );
    $stars_html  = str_repeat( '★', $stars_count )
                 . str_repeat( '☆', 5 - $stars_count );
 
    return sprintf(
        '<blockquote class="testimonial">
            <p class="testimonial__stars">%s</p>
            <p class="testimonial__body">%s</p>
            <footer class="testimonial__attribution">
                <strong>%s</strong>%s
            </footer>
        </blockquote>',
        esc_html( $stars_html ),
        wp_kses_post( $content ),
        esc_html( $atts['name'] ),
        $atts['company'] ? ', ' . esc_html( $atts['company'] ) : ''
    );
}
add_shortcode( 'testimonial', 'testimonial_shortcode' );

Использование:

[testimonial name="Sarah K." company="Acme Corp" stars="4"]
	Saved us hours every week.
[/testimonial]

Работает... но это всего лишь шорткод 🤷🏻‍♂️

Вот лишь некоторые проблемы с шорткодами:

  • Невидимость в редакторе. Автор видит [testimonial name="Sarah K." ...] в редакторе, а не отрисованную карточку. Предварительного просмотра нет.
  • Нет возможности обнаружения. Нужно знать о существовании шорткода и помнить названия его параметров. В пользовательском интерфейсе ничего не отображается.
  • Нет нативных элементов управления стилями. Настройка цвета, отступов или типографики требует пользовательского CSS или дополнительных атрибутов, подключённых вручную.
  • Внутренний контент не является форматированным текстом. Тело отзыва передаётся как обычная строка в $content — не как редактируемая область форматированного текста.

Шорткоды были правильным инструментом для своей эпохи. Редактор блоков предлагает нечто лучшее, но воспользоваться им было непросто. WordPress 7.0 предлагает ярлык в виде блоков только на PHP.

Для ясности: правильный новый способ создания блока Gutenberg по-прежнему представляет собой блок, зарегистрированный с JavaScript, с полным компонентом edit. Блоки только на PHP — это упрощённый путь, намеренно ограниченный серверными блоками, которым не нужно богатое редактирование на холсте. Они не являются заменой JavaScript-блоков, а представляют новый вариант для более простых случаев использования, где накладные расходы на конвейер сборки и компоненты React не оправданы.

Более простой вариант: блоки только на PHP

Давайте создадим тот же отзыв в виде пользовательского блока WordPress только на PHP. Рецепт: register_block_type() с 'autoRegister' => true в supports, плюс render_callback.

Вот полный код блока:

function my_plugin_register_testimonial_block() {
    register_block_type(
        'my-plugin/testimonial', // Block name: namespace/slug
        array(
            'title'      => 'Testimonial', // Shown in the block inserter
            'attributes' => array(
                // string attributes generate a text input in the sidebar
                'name'    => array(
                    'type'    => 'string',
                    'default' => '',
                ),
                'company' => array(
                    'type'    => 'string',
                    'default' => '',
                ),
                // integer attributes generate a number input
                'stars'   => array(
                    'type'    => 'integer',
                    'default' => 5,
                ),
                'body'    => array(
                    'type'    => 'string',
                    'default' => '',
                ),
            ),
            // render_callback is the PHP function that outputs the block's HTML
            'render_callback' => function ( $attributes ) {
                $stars_count = max( 1, min( 5, intval( $attributes['stars'] ) ) );
                $stars_html  = str_repeat( '★', $stars_count )
                             . str_repeat( '☆', 5 - $stars_count );
 
                // Translatable string for screen readers — standard WordPress i18n, nothing extra needed
                /* translators: %d: star rating out of 5 */
                $stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );
 
                return sprintf(
                    '<blockquote %s>
                        <p class="testimonial__stars" aria-label="%s">%s</p>
                        <p class="testimonial__body">%s</p>
                        <cite class="testimonial__attribution">
                            <strong>%s</strong>%s
                        </cite>
                    </blockquote>',
                    // Merges your class with editor-added colour, spacing, and typography styles
                    get_block_wrapper_attributes( array( 'class' => 'testimonial wp-block-quote' ) ),
                    esc_attr( $stars_label ),
                    esc_html( $stars_html ),
                    wp_kses_post( $attributes['body'] ),
                    esc_html( $attributes['name'] ),
                    $attributes['company'] ? ', ' . esc_html( $attributes['company'] ) : ''
                );
            },
            'supports' => array(
                // The key flag — tells WordPress to handle JS registration automatically
                'autoRegister' => true, 
                // The rest unlock native colour, typography, and spacing panels in the sidebar
                'color'      => array(
                    'background' => true,
                    'text'       => true,
                ),
                'typography' => array(
                    'fontSize' => true,
                ),
                'spacing'    => array(
                    'padding' => true,
                    'margin'  => true,
                ),
            ),
        )
    );
}
add_action( 'init', 'my_plugin_register_testimonial_block' );

Результат:

Пример пользовательского блока WordPress, созданного только на PHP
Блок отзыва только на PHP с автоматически генерируемыми элементами управления и живым предварительным просмотром на холсте редактора в сравнении с версией на шорткоде.

Здесь есть несколько моментов, на которые стоит обратить внимание. Во-первых, внутренний контент шорткода не имеет прямого эквивалента в блоках только на PHP. Тело отзыва становится атрибутом типа string, редактируемым из элементов управления инспектора боковой панели — однострочное текстовое поле, а не редактируемая область форматированного текста на холсте. Для короткой цитаты отзыва это приемлемо. Для более длинного основного текста вам понадобится блок, зарегистрированный с JavaScript, с компонентом RichText.

Во-вторых, get_block_wrapper_attributes() объединяет ваш класс с тем, что редактор добавляет для цвета, типографики и отступов — так что нативные панели стилей работают без дополнительного подключения CSS. render_callback получает массив $attributes, содержащий только значения, установленные пользователем; параметра $content нет, так как внутренний контент не поддерживается.

Что вы получаете по сравнению с версией на шорткоде:

  • Живой предварительный просмотр на холсте редактора. Больше никакого сырого синтаксиса шорткода — автор видит отрисованную карточку отзыва в процессе редактирования.
  • Автоматически генерируемые элементы управления. Имя, компания, тело (текстовые поля) и звёзды (числовое поле) автоматически появляются в элементах управления инспектора боковой панели.
  • Нативные панели цвета, шрифта и отступов. Берутся из supports — пользовательский CSS не нужен.
  • Возможность обнаружения. Блок появляется в инсерторе под своим именем с иконкой.

Готовность к переводу с первого дня

При работе с блоками только на PHP есть два отдельных аспекта перевода, и важно чётко понимать, что есть что.

Первый — это статические строки, встроенные в ваш PHP-шаблон: метки, текст кнопок, текст интерфейса. Они обрабатываются с помощью __() и _e(), как и в любом PHP-файле WordPress. В приведённом выше блоке примером является метка звёзд:

/* translators: %d: star rating out of 5 */
$stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );

Стандартные инструменты WordPress автоматически подхватывают их. Ничего дополнительного не требуется.

Второй аспект — это введённый пользователем контент, хранящийся в виде атрибутов блока: тело отзыва, имя рецензента, компания. Это контент, который ваши редакторы фактически вводят в блок, и __() его не затрагивает. На многоязычном сайте эти значения атрибутов необходимо переводить на каждый язык отдельно, и это не то, что WordPress обрабатывает самостоятельно.

Gato AI Translations for Polylang поддерживает блоки только на PHP из коробки — так же, как поддерживает Gutenberg, Bricks, Elementor и другие конструкторы страниц. Никакой дополнительной настройки не требуется.

Все строковые атрибуты автоматически регистрируются для перевода. Если конкретное поле не должно переводиться — внутренняя ссылка, URL, числовой код, хранящийся в виде строки — вы можете исключить его с помощью фильтра.

Для блока отзыва из этой статьи имя рецензента, компания и текст тела переводятся автоматически — никакой настройки, кроме установки плагина.

Что блоки только на PHP (пока) не могут делать

Текущие ограничения блоков только на PHP:

  • Нет внутренних блоков или вложенности. Вы не можете вставлять другие блоки внутрь блока только на PHP.
  • Нет редактирования форматированного текста на холсте. Компонент RichText требует JavaScript. Текстовые элементы управления отображаются только как текстовое поле в боковой панели.
  • Строковые поля боковой панели однострочные. Атрибут string становится TextControl, а не TextareaControl — не идеально для более длинного текста.
  • Нет атрибутов для выбора изображений или медиафайлов. Поддержка загрузки изображений/файлов запланирована для более позднего выпуска через Block Fields API.
  • Предварительный просмотр в редакторе имеет задержку туда-обратно. Изменения атрибутов запускают запрос к REST API для повторной отрисовки на сервере, поэтому предварительный просмотр не обновляется мгновенно.

Для простых структурированных блоков — отзывов, CTA, уведомлений, биографий авторов, бизнес-листингов — блоки только на PHP попадают в точку. Для всего, что требует богатого редактирования на холсте, регистрация с JavaScript остаётся правильным инструментом.

Что дальше

Блоки только на PHP в WordPress 7.0 делают разработку блоков доступной для любого PHP-разработчика. Один PHP-файл, один вызов register_block_type() — и у вас есть полностью функциональный блок Gutenberg с элементами управления боковой панели, живым предварительным просмотром на холсте и нативной поддержкой стилей. Вы пишете PHP. Вы получаете блок. Никаких инструментов. Никакой сборки. Никакого JavaScript.

Если вы создаёте многоязычные сайты, Gato AI Translations работает без проблем с блоками только на PHP — ваш контент доступен для перевода с первого дня.

Готовы идти дальше?


Узнайте, что будет дальше

Подпишитесь на нашу рассылку: узнавайте, когда мы выпускаем новую версию, запускаем новый плагин или хотим поделиться с вами новостями.