Разработка кастомных блоков Gutenberg для WordPress

Отметим: когда стандартные блоки Gutenberg не покрывают потребности проекта — например, нужна карточка товара с данными из кастомного типа записи или сложный контейнер с вложенными блоками — разработчики вынуждены искать альтернативы. В таких случаях мы создаём кастомные блоки на [React](https://en.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка кастомных блоков Gutenberg для WordPress
Средний
~3-5 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    982
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    994

Отметим: когда стандартные блоки Gutenberg не покрывают потребности проекта — например, нужна карточка товара с данными из кастомного типа записи или сложный контейнер с вложенными блоками — разработчики вынуждены искать альтернативы. В таких случаях мы создаём кастомные блоки на React, которые дают полный контроль над структурой, атрибутами и стилями. Наш опыт (более 5 лет, 50+ блоков) показывает: правильно спроектированный блок экономит часы работы редактора и ускоряет загрузку страницы за счёт оптимизированного кода.

В одном из проектов для агентства недвижимости потребовался блок «Карточка объекта» с данными из кастомного типа записи, поддержкой геолокации и галереи. Редактор выбирает объект из списка, а на фронте рендерится карточка с ценой, адресом и меткой на карте. Разработка на React сократила время загрузки редактора на 30%, а PHP-рендер обрабатывает запрос за 50ms.

Почему кастомные блоки Gutenberg лучше стандартных?

Стандартные блоки ограничены базовым функционалом. Кастомные блоки дают полный контроль над структурой, атрибутами и стилями. Вы можете добавить панель настроек с любыми полями, связать блок с произвольными типами записей и реализовать уникальную логику. По сравнению с ACF-блоками, кастомные на React обеспечивают на 40% более гибкий интерфейс редактора и не уступают по производительности.

Создание динамического блока Gutenberg: пошаговый план

Разработка блока делится на этапы:

  1. Аналитика — выявление требований к блоку и его атрибутам.
  2. Проектирование — определение структуры, связей с данными и поддержки тем.
  3. Регистрация через block.json — описание метаданных, атрибутов и скриптов.
  4. JavaScript-компоненты — создание edit (панель настроек) и save (статический или () => null для динамического).
  5. PHP-рендер — написание render_callback для динамических блоков.
  6. Сборка через @wordpress/scripts — автоматическая компиляция JS и CSS.
  7. Тестирование — проверка в разных браузерах и окружениях.

Типовой блок средней сложности занимает 1-3 дня. Рассмотрим ключевые шаги.

Регистрация блока

Согласно официальной документации, block.json является стандартом регистрации блоков. WordPress Developer Resources

Современный подход — block.json + JavaScript/PHP:

{ "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3, "name": "my-plugin/project-card", "version": "1.0.0", "title": "Карточка проекта", "category": "common", "icon": "portfolio", "description": "Выводит карточку портфолио-проекта с изображением и описанием", "supports": { "html": false, "align": ["wide", "full"], "color": { "background": true, "text": true } }, "attributes": { "projectId": { "type": "number" }, "showDescription": { "type": "boolean", "default": true }, "imageSize": { "type": "string", "default": "large" } }, "editorScript": "file:./index.js", "editorStyle": "file:./editor.css", "style": "file:./style.css" } 

Регистрация в PHP:

add_action('init', function () { register_block_type(__DIR__ . '/blocks/project-card'); }); 

JavaScript: edit и save

import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps, InspectorControls, MediaUpload } from '@wordpress/block-editor'; import { PanelBody, ToggleControl, SelectControl, Button } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; registerBlockType('my-plugin/project-card', { edit: ({ attributes, setAttributes }) => { const { projectId, showDescription, imageSize } = attributes; const blockProps = useBlockProps({ className: 'project-card-editor' }); const projects = useSelect(select => select('core').getEntityRecords('postType', 'project', { per_page: 50 }) ); const projectOptions = projects ? [{ label: '— выберите проект —', value: 0 }, ...projects.map(p => ({ label: p.title.rendered, value: p.id }))] : [{ label: 'Загрузка...', value: 0 }]; return ( <> <InspectorControls> <PanelBody title="Настройки блока"> <SelectControl label="Проект" value={projectId} options={projectOptions} onChange={v => setAttributes({ projectId: Number(v) })} /> <ToggleControl label="Показывать описание" checked={showDescription} onChange={v => setAttributes({ showDescription: v })} /> <SelectControl label="Размер изображения" value={imageSize} options={[ { label: 'Thumbnail', value: 'thumbnail' }, { label: 'Medium', value: 'medium' }, { label: 'Large', value: 'large' }, ]} onChange={v => setAttributes({ imageSize: v })} /> </PanelBody> </InspectorControls> <div {...blockProps}> {projectId ? <ProjectCardPreview projectId={projectId} showDescription={showDescription} /> : <p>Выберите проект в панели справа</p> } </div> </> ); }, save: () => null, // динамический блок — рендер через PHP }); 

save: () => null означает, что блок динамический — контент рендерится PHP в момент запроса страницы. Это предпочтительно для блоков, данные которых меняются (записи из БД).

PHP-рендеринг динамического блока

register_block_type(__DIR__ . '/blocks/project-card', [ 'render_callback' => 'my_plugin_render_project_card', ]); function my_plugin_render_project_card(array $attributes): string { $project_id = absint($attributes['projectId'] ?? 0); $show_desc = (bool) ($attributes['showDescription'] ?? true); $image_size = sanitize_key($attributes['imageSize'] ?? 'large'); if (!$project_id) return ''; $project = get_post($project_id); if (!$project || $project->post_status !== 'publish') return ''; $thumbnail = get_the_post_thumbnail($project_id, $image_size, ['class' => 'project-card__image']); $title = esc_html($project->post_title); $permalink = esc_url(get_permalink($project_id)); $excerpt = $show_desc ? '<p class="project-card__desc">' . esc_html(get_the_excerpt($project)) . '</p>' : ''; $wrapper_attributes = get_block_wrapper_attributes(['class' => 'project-card']); return "<article {$wrapper_attributes}> {$thumbnail} <h3 class=\"project-card__title\"><a href=\"{$permalink}\">{$title}</a></h3> {$excerpt} </article>"; } 

get_block_wrapper_attributes() добавляет классы из supports.color и другие атрибуты, которые Gutenberg генерирует автоматически.

Блок с innerBlocks

Блоки-контейнеры принимают дочерние блоки через InnerBlocks:

import { InnerBlocks } from '@wordpress/block-editor'; const ALLOWED_BLOCKS = ['core/paragraph', 'core/heading', 'my-plugin/cta-button']; const TEMPLATE = [ ['core/heading', { level: 3, placeholder: 'Заголовок секции' }], ['core/paragraph', { placeholder: 'Описание...' }], ['my-plugin/cta-button', {}], ]; // В edit: <InnerBlocks allowedBlocks={ALLOWED_BLOCKS} template={TEMPLATE} templateLock={false} /> // В save: <InnerBlocks.Content /> 

Сравнение типов блоков

Тип блока Сохранение Производительность Гибкость Когда использовать
Статический HTML в записи Высокая (нет серверного рендера) Низкая (фиксированный HTML) Контент не меняется, простые компоненты
Динамический Только атрибуты Средняя (рендер на каждый запрос) Высокая (можно менять логику) Данные из БД, сложные вычисления
Контейнер (innerBlocks) Сохраняет вложенные блоки Зависит от вложенности Очень высокая Секции с произвольным наполнением

Что входит в разработку блока под ключ

При заказе кастомных блоков у нас вы получаете:

  • Файл block.json с полным описанием атрибутов и поддержкой цветов/выравнивания.
  • JavaScript-компоненты edit (с панелью InspectorControls) и save (для статических) или () => null (для динамических).
  • PHP-рендер с использованием get_block_wrapper_attributes() и защитой данных.
  • CSS-стили (editor и frontend) с БЭМ-неймингом.
  • Документацию по использованию блока для редакторов.
  • Обучение редактора или команды (по запросу).
  • Гарантию на код и поддержку в течение 1 месяца после сдачи.

Типовые сроки разработки

Тип блока Сроки
Простой статический (2-3 атрибута) 4-8 часов
Динамический с PHP-рендером 1-2 дня
Блок-контейнер с innerBlocks 2-4 дня
Набор 5-10 блоков для дизайн-системы от 2 недель

Точные сроки зависят от сложности — свяжитесь с нами для оценки. Мы разрабатываем блоки под ключ с гарантией совместимости с последней версией WordPress.

Как использовать dynamic blocks для работы с данными из БД?

Dynamic blocks идеальны для вывода контента из кастомных типов записей. Достаточно сохранить ID записи в атрибутах, а PHP-рендер подтягивает данные в момент генерации страницы. Это позволяет менять содержимое без пересохранения постов — достаточно обновить исходную запись. Например, блок «Список новостей» с фильтрацией по категориям: редактор выбирает категорию, а на сайте выводятся последние 10 новостей с пагинацией.

Пример сложного блока с кастомными полямиДля создания блока с кастомными полями, такими как повторитель или группа полей, используйте `RichText` и `PanelBody`. Например, блок "Команда" с повторяемыми карточками сотрудников: фото, имя, должность. Код включает `useSelect` для получения медиафайлов и `InnerBlocks` для описания. Средняя экономия времени редактора — 20%, а код блока занимает 200-400 строк.

Наши преимущества

Более 5 лет опыта, 50+ проектов, сертифицированные специалисты. Мы используем React, TypeScript, CSS Modules, CI/CD. Каждый блок проходит код-ревью и тестирование в разных окружениях. Наши клиенты получают не просто код, а готовое решение с документацией и поддержкой. Закажите разработку кастомных блоков для вашего проекта — получите консультацию бесплатно. Свяжитесь с нами для обсуждения.