В редакторе Gutenberg для WordPress динамические блоки позволяют выводить контент, который обновляется на стороне сервера при каждом отображении. В отличие от статических блоков, динамические блоки могут использовать React для интерфейса редактирования и PHP для рендеринга на фронтенде. В этой статье подробно разберём, как создать такой блок с нуля, используя современный подход и инструменты WordPress.
Что такое динамические блоки Gutenberg и зачем они нужны
Динамические блоки — это блоки, содержимое которых не сохраняется в базе данных в виде HTML, а формируется при отображении страницы. Это позволяет подгружать актуальные данные, например, последние записи, статистику, результаты опросов и т.д. При этом интерфейс редактирования строится на React, что обеспечивает удобство и интерактивность.
Преимущества динамических блоков:
- Актуальность данных при каждом показе страницы.
- Возможность реализовать сложную логику отображения на сервере.
- Использование React для гибкой настройки интерфейса редактора.
Настройка среды и создание плагина для динамического блока
Для начала нужно создать плагин, который зарегистирует блок и подключит необходимые скрипты. Структура:
- plugin-dir/
- plugin-dir/block.js — React-компоненты для редактора
- plugin-dir/block.php — регистрация блока и серверный рендеринг
В файле block.php подключаем скрипты и регистрируем блок:
<?php
function wpplugins_register_dynamic_block() {
wp_register_script(
'wpplugins-block-editor',
plugins_url('block.js', __FILE__),
array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-i18n'),
filemtime(plugin_dir_path(__FILE__) . 'block.js')
);
register_block_type('wpplugins/dynamic-block', array(
'editor_script' => 'wpplugins-block-editor',
'render_callback' => 'wpplugins_render_dynamic_block',
'attributes' => array(
'numberOfPosts' => array(
'type' => 'number',
'default' => 5,
),
),
));
}
add_action('init', 'wpplugins_register_dynamic_block');
function wpplugins_render_dynamic_block($attributes) {
$number = isset($attributes['numberOfPosts']) ? intval($attributes['numberOfPosts']) : 5;
$posts = get_posts(array('numberposts' => $number));
if (empty($posts)) {
return '<p>Нет доступных записей.</p>';
}
$output = '<ul>';
foreach ($posts as $post) {
$output .= '<li><a href="' . get_permalink($post) . '">' . esc_html(get_the_title($post)) . '</a></li>';
}
$output .= '</ul>';
return $output;
}
?>Этот код регистрирует блок с атрибутом numberOfPosts и определяет функцию рендеринга, которая выводит список последних публикаций.
Создание интерфейса редактора на React (JavaScript)
В файле block.js реализуем редактор блока с настройкой числа выводимых записей:
const { registerBlockType } = wp.blocks;
const { TextControl, PanelBody, RangeControl } = wp.components;
const { InspectorControls } = wp.blockEditor || wp.editor;
const { __ } = wp.i18n;
registerBlockType('wpplugins/dynamic-block', {
title: __('Динамический список записей', 'wpplugins'),
icon: 'list-view',
category: 'widgets',
attributes: {
numberOfPosts: {
type: 'number',
default: 5,
},
},
edit: (props) => {
const { attributes: { numberOfPosts }, setAttributes } = props;
return (
<>
<InspectorControls>
<PanelBody title={__('Настройки блока', 'wpplugins')} initialOpen={true}>
<RangeControl
label={__('Количество записей', 'wpplugins')}
value={numberOfPosts}
onChange={(value) => setAttributes({ numberOfPosts: value })}
min={1}
max={20}
/>
</PanelBody>
</InspectorControls>
<div>
<strong>{__('Динамический блок: последние записи', 'wpplugins')}</strong>
<p>{__('Количество записей: ', 'wpplugins')}{numberOfPosts}</p>
</div>
</>
);
},
save: () => {
// Содержимое динамического блока рендерится на сервере
return null;
},
});Здесь мы используем панель настроек (InspectorControls) с ползунком (RangeControl) для выбора количества записей. Метод save возвращает null, так как HTML формируется сервером.
Оптимизация и советы по работе с динамическими блоками
Динамические блоки требуют внимания к производительности, поскольку при каждом отображении страницы вызывается PHP-функция рендеринга. Чтобы избежать задержек:
- Используйте кеширование результатов с помощью Transients API WordPress.
- Минимизируйте количество запросов к базе данных в функции рендера.
- Проверяйте корректность атрибутов и защищайте вывод с помощью функций экранирования.
Пример реализации кеширования в wpplugins_render_dynamic_block:
function wpplugins_render_dynamic_block($attributes) {
$number = isset($attributes['numberOfPosts']) ? intval($attributes['numberOfPosts']) : 5;
$cache_key = 'wpplugins_dynamic_block_posts_' . $number;
$output = get_transient($cache_key);
if ($output === false) {
$posts = get_posts(array('numberposts' => $number));
if (empty($posts)) {
return '<p>Нет доступных записей.</p>';
}
$output = '<ul>';
foreach ($posts as $post) {
$output .= '<li><a href="' . get_permalink($post) . '">' . esc_html(get_the_title($post)) . '</a></li>';
}
$output .= '</ul>';
set_transient($cache_key, $output, HOUR_IN_SECONDS);
}
return $output;
}Полезные плагины для разработки блоков Gutenberg
Для упрощения разработки динамических блоков рекомендуем обратить внимание на:
- Clearfy Pro — оптимизация и улучшение производительности WordPress, полезна при работе с кастомными блоками.
- WPCommunity — для расширения возможностей REST API, если нужно динамически подгружать данные.
Тестирование и отладка динамических блоков
Для проверки работы блока используйте стандартные инструменты разработчика браузера и консоль WordPress. Важно проверять, что серверный рендеринг возвращает корректный HTML, а редактор блоков отображает все настройки. При необходимости подключайте console.log в React-компонентах и error_log в PHP.
Также рекомендуется проверять кроссбраузерность и совместимость с другими плагинами, чтобы избежать конфликтов.