В редакторе Gutenberg для WordPress часто возникает необходимость создавать визуальные превью блоков — так называемые снимки (thumbnails) — для административной панели или пользовательских интерфейсов. Это полезно, когда вы разрабатываете собственные блоки или хотите улучшить UX при выборе блоков в редакторе.
Зачем нужны автоматические снимки для блоков Gutenberg
Автоматические снимки позволяют визуально отображать содержимое блока или его состояние без необходимости вручную создавать и загружать изображения. Это особенно актуально для динамических блоков, где содержимое часто меняется или зависит от пользовательских данных.
Кроме того, наличие таких превью упрощает работу редакторов и контент-менеджеров, снижая ошибки и ускоряя процесс наполнения сайта.
Как работает механизм снимков в Gutenberg
Gutenberg использует React и JavaScript для рендеринга блоков. В административной части редактора можно определить функцию save, которая возвращает HTML-код содержимого блока. Однако для динамических блоков используется функция рендеринга на сервере (PHP).
Чтобы создать автоматический снимок, нам нужно сгенерировать изображение из этого HTML. В WordPress нет встроенного механизма для рендеринга HTML в картинку, поэтому мы используем несколько подходов:
- Серверный рендеринг с использованием библиотеки
dompdfили аналогичных. - Рендеринг в браузере и конвертация DOM в canvas с помощью JavaScript (например, html2canvas), затем сохранение изображения в медиабиблиотеку.
- Использование плагинов, которые автоматизируют создание превью для блоков.
Пример: автоматическое создание снимка блока с помощью html2canvas и AJAX
Рассмотрим практический пример, где при сохранении поста будет происходить генерация снимка для пользовательского блока.
Шаг 1: JavaScript для захвата блока и отправки снимка на сервер
document.addEventListener('DOMContentLoaded', function() {
const blockSelector = '.wp-block-myplugin-customblock';
const blockElement = document.querySelector(blockSelector);
if (!blockElement) return;
html2canvas(blockElement).then(canvas => {
canvas.toBlob(function(blob) {
const formData = new FormData();
formData.append('action', 'wptour_save_block_screenshot');
formData.append('image', blob, 'block-screenshot.png');
formData.append('post_id', wp.data.select('core/editor').getCurrentPostId());
fetch(wpApiSettings.ajax_url, {
method: 'POST',
credentials: 'same-origin',
body: formData
})
.then(response => response.json())
.then(data => {
if(data.success) {
console.log('Снимок блока успешно сохранён', data.url);
} else {
console.error('Ошибка сохранения снимка');
}
});
});
});
});
Этот скрипт использует библиотеку html2canvas, которая позволяет сделать "скриншот" DOM-элемента и получить изображение в формате Blob.
Шаг 2: PHP обработчик AJAX для сохранения изображения
add_action('wp_ajax_wptour_save_block_screenshot', 'wptour_save_block_screenshot_callback');
function wptour_save_block_screenshot_callback() {
if (empty($_FILES['image']) || !isset($_POST['post_id'])) {
wp_send_json_error('Нет данных для сохранения');
}
$post_id = intval($_POST['post_id']);
$file = $_FILES['image'];
// Проверяем файл
if ($file['error'] !== UPLOAD_ERR_OK) {
wp_send_json_error('Ошибка загрузки изображения');
}
// Загружаем файл в медиабиблиотеку
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attachment_id = media_handle_upload('image', $post_id);
if (is_wp_error($attachment_id)) {
wp_send_json_error('Ошибка при сохранении в медиабиблиотеку');
}
$url = wp_get_attachment_url($attachment_id);
wp_send_json_success(['url' => $url]);
}
Этот обработчик принимает изображение, загружает его в медиабиблиотеку и возвращает URL сохранённого файла.
Как интегрировать снимки в административную панель WordPress
После создания снимков можно отображать их в списках постов, настройках блоков или кастомных разделах. Например, для кастомного блока можно в edit компоненте добавить отображение изображения превью из медиабиблиотеки.
Добавление превью в кастомный блок
В JavaScript-файле блока добавьте:
const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
const { Button } = wp.components;
const WPTourEdit = (props) => {
const { attributes, setAttributes } = props;
return (
<div>
{attributes.screenshotURL ? <img src={attributes.screenshotURL} alt="Превью блока" style={{maxWidth: '100%'}} /> : null}
<MediaUploadCheck>
<MediaUpload
onSelect={media => setAttributes({ screenshotURL: media.url })}
allowedTypes={[ 'image' ]}
value={attributes.screenshotID}
render={({ open }) => (
<Button onClick={open} variant="primary">Выбрать превью</Button>
)}
/>
</MediaUploadCheck>
</div>
);
};
Так вы даёте редактору возможность вручную подгружать снимок или автоматически обновлять его через AJAX.
Полезные плагины для работы с превью и визуализацией блоков
Существуют плагины, облегчающие создание и управление превью блоков:
- Block Preview — позволяет создавать превью для блоков без сложного кода.
- Clearfy Pro — оптимизирует работу сайта и может помочь с кэшированием и генерацией изображений.
Рекомендации и подводные камни при создании автоматических снимков
При реализации автоматического создания снимков стоит учитывать следующие моменты:
- Производительность. Генерация изображений может быть ресурсоёмкой, поэтому лучше делать это асинхронно, например, при сохранении или обновлении поста.
- Размеры изображений. Оптимизируйте получаемые файлы для быстрой загрузки и минимального потребления места на сервере.
- Безопасность. Проверяйте и фильтруйте входящие данные, особенно если используете сторонние библиотеки или API.
- Кроссбраузерность. html2canvas и другие JS-библиотеки работают не идеально во всех браузерах, тестируйте на целевых.
Выводы
Автоматические снимки для блоков Gutenberg — отличный способ улучшить интерфейс редактора и упростить работу с контентом. Используя комбинацию JavaScript (html2canvas), AJAX и PHP для загрузки изображений, можно реализовать гибкое и расширяемое решение.
Дополнительно рекомендуем изучить плагины на WPSHOP.ru для оптимизации и расширения функционала вашего WordPress-сайта.