В этом материале рассмотрим, как создать динамический Gutenberg блок, который подгружает данные из REST API WordPress и отображает их внутри редактора и на фронтенде. Такой подход полезен для вывода актуальной информации, например, списка последних записей, отзывов или товаров, без необходимости вручную обновлять содержимое блока.
Что такое динамический Gutenberg блок и зачем использовать REST API
В Gutenberg существуют два типа блоков: статические и динамические. Статические блоки рендерятся только в редакторе и сохраняют весь HTML в контенте поста. Динамические блоки же выводятся через PHP функцию при рендеринге страницы, что позволяет актуализировать контент.
Использование REST API позволяет загружать данные асинхронно на стороне клиента — в редакторе или на сайте — что даёт гибкость в построении интерактивных блоков, отображающих свежую информацию без перезагрузки страницы.
В нашем примере мы создадим динамический блок, который в редакторе отображает кнопку для загрузки данных из REST API, а на фронтенде автоматически выводит список последних 5 записей.
Создание базового динамического блока с регистрацией в PHP
Начнём с регистрации динамического блока в PHP. Создайте файл плагина или добавьте в functions.php темы следующий код:
function wpblock_register_dynamic_block() {
register_block_type('wpblock/dynamic-rest-api', [
'render_callback' => 'wpblock_render_dynamic_rest_api_block',
'attributes' => [
'postCount' => [
'type' => 'number',
'default' => 5,
],
],
]);
}
add_action('init', 'wpblock_register_dynamic_block');
function wpblock_render_dynamic_rest_api_block($attributes) {
$count = isset($attributes['postCount']) ? intval($attributes['postCount']) : 5;
$recent_posts = wp_get_recent_posts([
'numberposts' => $count,
'post_status' => 'publish',
]);
if (empty($recent_posts)) {
return '<p>Нет доступных записей.</p>';
}
$output = '<ul class="wpblock-recent-posts">';
foreach ($recent_posts as $post) {
$title = esc_html($post['post_title']);
$link = esc_url(get_permalink($post['ID']));
$output .= "<li><a href=\"$link\">$title</a></li>";
}
$output .= '</ul>';
return $output;
}Этот код регистрирует блок с именем wpblock/dynamic-rest-api, который имеет атрибут postCount для задания количества выводимых постов. Функция wpblock_render_dynamic_rest_api_block формирует HTML список последних записей.
Добавление JavaScript для интерфейса блока в редакторе Gutenberg
Теперь создадим интерфейс блока на React, чтобы пользователь мог изменить количество постов и вручную подгружать данные из REST API прямо в редакторе. Создайте файл block.js и подключите его в плагине:
function wpblock_enqueue_block_assets() {
wp_register_script(
'wpblock-dynamic-rest-api-block',
plugins_url('block.js', __FILE__),
['wp-blocks', 'wp-element', 'wp-components', 'wp-editor', 'wp-data'],
filemtime(plugin_dir_path(__FILE__) . 'block.js')
);
register_block_type('wpblock/dynamic-rest-api', [
'editor_script' => 'wpblock-dynamic-rest-api-block',
'render_callback' => 'wpblock_render_dynamic_rest_api_block',
'attributes' => [
'postCount' => [
'type' => 'number',
'default' => 5,
],
],
]);
}
add_action('init', 'wpblock_enqueue_block_assets');В block.js реализуем следующий код:
const { registerBlockType } = wp.blocks;
const { useState, useEffect } = wp.element;
const { TextControl, Button, Spinner } = wp.components;
registerBlockType('wpblock/dynamic-rest-api', {
title: 'Динамический блок с REST API',
icon: 'admin-post',
category: 'widgets',
attributes: {
postCount: {
type: 'number',
default: 5,
},
},
edit: (props) => {
const { attributes, setAttributes } = props;
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchPosts = () => {
setLoading(true);
setError(null);
wp.apiFetch({
path: `/wp/v2/posts?per_page=${attributes.postCount}`,
})
.then((data) => {
setPosts(data);
})
.catch(() => {
setError('Ошибка загрузки данных.');
})
.finally(() => {
setLoading(false);
});
};
useEffect(() => {
fetchPosts();
}, [attributes.postCount]);
return (
<div className="wpblock-dynamic-rest-api-block">
<TextControl
label="Количество записей"
type="number"
value={attributes.postCount}
onChange={(value) => setAttributes({ postCount: parseInt(value) || 1 })}
min={1}
max={20}
/>
<Button isPrimary onClick={fetchPosts} disabled={loading}>Загрузить записи</Button>
{loading && <Spinner />}
{error && <p style={{ color: 'red' }}>{error}</p>}
<ul>
{posts.map((post) => (
<li key={post.id}><a href={post.link} target="_blank" rel="noopener noreferrer">{post.title.rendered}</a></li>
))}
</ul>
</div>
);
},
save: () => {
return null; // Динамический блок, рендеринг на сервере
},
});Пояснения к коду и советы по улучшению
В редакторе при изменении количества записей автоматически вызывается useEffect для загрузки свежих данных с помощью wp.apiFetch по REST API WordPress. Это позволяет видеть в редакторе актуальный список без перезагрузки.
На фронтенде же список формируется функцией PHP через wp_get_recent_posts, чтобы обеспечить SEO-дружественный и кэшируемый HTML-код.
Если вам нужно получить данные из кастомного REST API или с других эндпоинтов, замените путь в wp.apiFetch и логику выборки в PHP соответственно. Например, для пользовательских типов записей или таксономий.
Для оптимизации загрузки используйте кэширование данных при помощи Transients API или внешних решений, особенно если источник данных тяжёлый.
Подключение стилей и кастомизация
Не забудьте добавить стили для блока, чтобы он выглядел аккуратно как в редакторе, так и на сайте. Для этого зарегистрируйте CSS-файлы и подключите их через enqueue_block_assets и enqueue_block_editor_assets.
Также можно расширить функционал блока, добавив фильтрацию, пагинацию или сортировку записей, что сделает его полезнее для сайтов с большим объёмом контента.
Пример ссылки на плагин с UTM метками
Если хотите использовать готовые решения для управления Gutenberg блоками или оптимизации REST API, рекомендуем посмотреть плагины на wpshop.ru.