В современных проектах на WordPress часто возникает необходимость создавать гибкие Gutenberg блоки, которые не просто отображают статический контент, а взаимодействуют с внешними данными и управляются состоянием вне самого блока. В этой статье мы подробно рассмотрим, как разработать динамический Gutenberg блок с внешним управлением состоянием, используя React-хуки и REST API WordPress.
Почему важно внешнее управление состоянием в Gutenberg блоках
Стандартные динамические блоки в Gutenberg рендерятся на сервере, что хорошо для отображения контента, но ограничивает интерактивность на клиенте. В то же время, чисто клиентские блоки могут иметь сложную логику состояния, которую трудно контролировать, если состояние хранится внутри блока.
Внешнее управление состоянием позволяет:
- Обеспечить синхронизацию данных между разными блоками на странице
- Использовать централизованные состояния, например, через React Context или Redux
- Динамически обновлять контент блока без перезагрузки страницы
Это особенно полезно при интеграции с плагинами, которые расширяют REST API, или при создании сложных интерфейсов с фильтрами и настройками.
Создаем базовый динамический блок для WordPress
Начнем с регистрации базового блока, который будет рендериться на сервере и поддерживать динамическое обновление. В файле плагина добавим PHP код:
<?php
function wpblock_register_dynamic_block() {
register_block_type('wpblock/dynamic-state-block', array(
'render_callback' => 'wpblock_render_dynamic_state_block',
'attributes' => array(
'content' => array(
'type' => 'string',
'default' => '',
),
),
));
}
add_action('init', 'wpblock_register_dynamic_block');
function wpblock_render_dynamic_state_block($attributes) {
$content = isset($attributes['content']) ? esc_html($attributes['content']) : 'Загрузка...';
return '<div class="wpblock-dynamic-state">' . $content . '</div>';
}
?>
Этот код регистрирует блок с одним атрибутом content, который будет выводиться на фронтенде.
Добавляем клиентскую часть с внешним состоянием
Далее на стороне JavaScript создадим интерфейс блока, который будет получать и изменять состояние вне себя. Для этого используем React Context и хук useContext. Пример кода в файле block.js:
import { registerBlockType } from '@wordpress/blocks';
import { useState, useEffect, createContext, useContext } from '@wordpress/element';
import { TextControl } from '@wordpress/components';
const WpblockStateContext = createContext();
function WpblockProvider({ children }) {
const [state, setState] = useState('Initial state from context');
return (
<WpblockStateContext.Provider value={{ state, setState }}>
{children}
</WpblockStateContext.Provider>
);
}
function DynamicStateBlockEdit(props) {
const { attributes, setAttributes } = props;
const { state, setState } = useContext(WpblockStateContext);
useEffect(() => {
setAttributes({ content: state });
}, [state]);
return (
<div>
<TextControl
label="Изменить состояние блока"
value={state}
onChange={(value) => setState(value)}
/>
</div>
);
}
registerBlockType('wpblock/dynamic-state-block', {
title: 'Динамический блок с внешним состоянием',
category: 'widgets',
attributes: {
content: {
type: 'string',
default: '',
},
},
edit: (props) => (
<WpblockProvider>
<DynamicStateBlockEdit {...props} />
</WpblockProvider>
),
save: () => {
return null; // Рендер на сервере
},
});
Здесь мы создаем контекст WpblockStateContext, который хранит состояние, и провайдер, оборачивающий редактор блока. Внутри редактора можно менять значение, которое синхронизируется с атрибутом блока.
Синхронизация с REST API для сохранения состояния
Чтобы сохранить состояние блока вне редактора, например, в базе данных, можно использовать REST API WordPress. Ниже пример запроса на обновление мета-поля поста, связанного с блоком:
function wpblock_update_post_meta(postId, metaKey, value) {
return wp.apiFetch({
path: `/wp/v2/posts/${postId}`,
method: 'POST',
data: {
meta: {
[metaKey]: value
}
}
});
}
Для корректной работы нужно зарегистрировать мета-поле с параметром 'show_in_rest' => true на PHP:
function wpblock_register_post_meta() {
register_post_meta('post', 'wpblock_dynamic_content', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
));
}
add_action('init', 'wpblock_register_post_meta');
В редакторе можно вызвать wpblock_update_post_meta(postId, 'wpblock_dynamic_content', state) для сохранения.
Примеры полезных плагинов для работы с динамическими блоками
Для расширения функциональности динамических блоков можно использовать плагины, такие как:
- Clearfy Pro — оптимизация и управление скриптами для ускорения загрузки блоков.
- WPRemark — улучшение отзывов, которые можно встроить в динамические блоки.
Эти инструменты помогают сделать блоки более производительными и функциональными.
Заключение
Внешнее управление состоянием в Gutenberg блоках — мощный инструмент для создания интерактивных и гибких интерфейсов в WordPress. Использование React Context и REST API позволяет синхронизировать данные между блоками и сохранять их в базе. Приведенный пример дает базовое понимание, как реализовать такую архитектуру. Дальше можно расширять логику, интегрировать с другими плагинами и создавать сложные пользовательские интерфейсы.