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

Відзначимо: коли стандартні блоки Gutenberg не покривають потреби проекту — наприклад, потрібна картка товару з даними з кастомного типу запису або складний контейнер з вкладеними блоками — розробники змушені шукати альтернативи. У таких випадках ми створюємо кастомні блоки на [React](https://en.wik

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

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

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

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Відзначимо: коли стандартні блоки 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. Кожен блок проходить код-рев'ю та тестування в різних оточеннях. Наші клієнти отримують не просто код, а готове рішення з документацією та підтримкою. Замовте розробку кастомних блоків для вашого проекту — отримайте консультацію безкоштовно. Зв'яжіться з нами для обговорення.