title: >- Анатомія block.json (Block API v3), колекції метаданих та архітектура сучасного блока description: >- Глибокий розбір специфікації block.json у WordPress 7.0+ «Armstrong» (Block API v3): ізольований iframe-редактор, ES-модулі фронтенду (viewScriptModule), контекстне дерево (providesContext / usesContext), компіляція маніфесту wp_register_block_metadata_collection() та умовне завантаження асетів. module: gutenberg-blocks order: 1 difficulty: intermediate estimatedTime: 35 хв topics:
У ранніх версіях Gutenberg реєстрація блока була розірвана між двома світами: частина конфігурації дублювалася в JavaScript усередині registerBlockType(), а частина — у PHP. Це призводило до розсинхронізації схеми атрибутів під час серверного рендерингу (SSR), неможливості проаналізувати залежності блока без виконання JS-бандла та примусового завантаження сотень кілобайт CSS і JS на кожній сторінці сайту.
У WordPress 7.0+ («Armstrong») єдиним джерелом істини (Single Source of Truth) для будь-якого блока є декларативний маніфест block.json специфікації Block API v3 ("apiVersion": 3). Цей JSON-файл одночасно керує чотирма підсистемами ядра:
apiVersion: 3): гарантує, що стилі адмінки WordPress (wp-admin) ніколи не проникнуть у верстку вашого блока, а сам блок коректно масштабується в режимах попереднього перегляду планшета та смартфона.should_load_separate_core_block_assets): ядро парсить post_content перед відправленням відповіді та інжектує на фронтенд (style, viewStyle, viewScriptModule) виключно ті CSS/JS-модулі, чиї блоки дійсно присутні на поточній сторінці.providesContext / usesContext): дозволяє батьківським блокам передавати стан дочірнім блокам на будь-яку глибину без глобальних змінних і prop-drilling.wp_register_block_metadata_collection): усуває дисковий I/O (file_get_contents + json_decode) під час реєстрації десятків блоків у великих дизайн-системах.Уявіть block.json як вантажний маніфест контейнера в автоматизованому морському порту (Ядро WordPress 7.0+). Портовому крану не потрібно відкривати контейнер і запускати двигун усередині (виконувати ваш React-бандл index.js), щоб дізнатися його габарити, вагу, температурний режим і пункт призначення. Прочитавши лише декларативну бірку block.json, сервер миттєво розуміє:
<!-- wp:agentic/metric-card {...} -->;theme.json v3) потрібно автоматично згенерувати в правому сайдбарі редактора через секцію supports;viewScriptModule) необхідно підключити через <script type="module"> у браузері відвідувача.ЄДИНИЙ МАНІФЕСТ: block.json (apiVersion: 3)
│
┌────────────────────────────────┼────────────────────────────────┐
▼ ▼ ▼
┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐
│ КОНТУР PHP (Сервер) │ │ КОНТУР EDITOR (Iframe)│ │ КОНТУР FRONTEND (Edge)│
├───────────────────────┤ ├───────────────────────┤ ├───────────────────────┤
│ • Валідація атрибутів │ │ • editorScript (React)│ │ • style / viewStyle │
│ • render: render.php │ │ • editorStyle │ │ • viewScriptModule │
│ • Передача $context │ │ • Генерація Inspector │ │ (Native ES Modules) │
│ • Умовний Enqueue │ │ Controls із supports│ │ • Interactivity API │
└───────────────────────┘ └───────────────────────┘ └───────────────────────┘Збирач компілює TypeScript/SCSS у директорію build/, генерує .asset.php з хешами версій і збирає єдиний blocks-manifest.php для всієї бібліотеки.
PHP реєструє колекцію через wp_register_block_metadata_collection() і завантажує блоки з пам'яті без звернень до десятків JSON-файлів на диску.
У Gutenberg блок монтується всередину ізольованого <iframe> полотна; ядро автоматично будує UI-панелі кольорів, відступів і меж за декларацією supports.
Під час збереження публікації атрибути валідуються за схемою та серіалізуються в post_content як структурований коментар <!-- wp:namespace/slug -->.
Під час рендерингу сторінки ядро виявляє блок, викликає render.php і підключає viewScriptModule через нативний Import Map браузера ЛИШЕ для цієї сторінки.
В інженерних проєктах Fullstack Agentic Lab грамотне проєктування block.json вирішує чотири ключові завдання:
editorScript (важкий React-код адмінки) та легкого viewScriptModule (< 3 KB), відвідувач сайту отримує 0 байт коду редактора.supports): замість написання сотень рядків кастомних ColorPalette, BoxControl та FontSizePicker у React, активація "spacing", "color", "typography" та "shadow" у block.json безкоштовно підключає нативний UI Gutenberg, синхронізований із токенами theme.json v3."supports": { "interactivity": true } вмикає клієнтську гідратацію директив data-wp-* та швидку клієнтську навігацію без перезавантаження сторінки.wp_register_block_types_from_metadata_collection() з нульовим оверхедом дискової системи.Порівняємо застарілу реєстрацію блоків (Block API v1/v2 з ручним wp_enqueue_script) і сучасний стандарт Block API v3 у WordPress 7.0+:
Нижче наведено еталонний виробничий артефакт для WordPress 7.0+ та PHP 8.4+, що містить повну специфікацію block.json (apiVersion: 3) для інтерактивної картки телеметрії та серверний завантажувач колекції метаданих із нульовим дисковим I/O.
<?php
/**
* Plugin Name: Fullstack Agentic Lab — Block API v3 & Metadata Collection Engine
* Description: Миттєва реєстрація бібліотеки блоків через передкомпільований маніфест.
* Version: 3.2.0
* Requires at least: 6.8
* Requires PHP: 8.4
* Author: Artur Yusupov (Fullstack Agentic Lab)
*/
declare(strict_types=1);
namespace AgenticLab\Blocks;
defined('ABSPATH') || exit;
final readonly class BlockLibraryRegistrar
{
public function __construct(
private string $buildDir,
private string $manifestFile,
) {}
public function registerHooks(): void
{
add_action('init', $this->registerAllBlocks(...), 10);
add_filter('block_categories_all', $this->registerCustomCategory(...), 10, 1);
}
/**
* Реєструє всю колекцію блоків за O(1) звернень до диска (WordPress 6.8 / 7.0+).
*/
public function registerAllBlocks(): void
{
// Примусово вмикаємо роздільне завантаження CSS тільки для блоків, що використовуються на сторінці
add_filter('should_load_separate_core_block_assets', '__return_true');
if (function_exists('wp_register_block_types_from_metadata_collection')) {
wp_register_block_types_from_metadata_collection($this->buildDir, $this->manifestFile);
return;
}
// Fallback для середовищ із ручним обходом після реєстрації колекції
if (function_exists('wp_register_block_metadata_collection') && is_readable($this->manifestFile)) {
wp_register_block_metadata_collection($this->buildDir, $this->manifestFile);
/** @var array<string, array<string, mixed>> $manifest */
$manifest = require $this->manifestFile;
foreach (array_keys($manifest) as $blockFolder) {
register_block_type($this->buildDir . '/' . $blockFolder);
}
}
}
/**
* Додає фірмову категорію блоків в інсертер Gutenberg.
*
* @param array<int, array<string, mixed>> $categories
* @return array<int, array<string, mixed>>
*/
public function registerCustomCategory(array $categories): array
{
array_unshift($categories, [
'slug' => 'agentic-lab-architecture',
'title' => 'Fullstack Agentic Lab',
'icon' => 'performance',
]);
return $categories;
}
}
(new BlockLibraryRegistrar(
buildDir: __DIR__ . '/build/blocks',
manifestFile: __DIR__ . '/build/blocks-manifest.php',
))->registerHooks();
/*
* ============================================================================
* ЕТАЛОННИЙ ФАЙЛ: build/blocks/telemetry-card/block.json (Block API v3)
* ============================================================================
* {
* "$schema": "https://schemas.wp.org/trunk/block.json",
* "apiVersion": 3,
* "name": "agentic-lab/telemetry-card",
* "version": "3.2.0",
* "title": "Architecture Telemetry Card",
* "category": "agentic-lab-architecture",
* "icon": "chart-area",
* "description": "Інтерактивна картка метрик інфраструктури з підтримкою Interactivity API та Block Context.",
* "keywords": ["telemetry", "metrics", "benchmark", "agentic"],
* "textdomain": "agentic-lab",
* "attributes": {
* "serviceName": {
* "type": "string",
* "default": "Edge Worker Gateway"
* },
* "latencyP95Ms": {
* "type": "number",
* "default": 14
* },
* "uptimePercent": {
* "type": "number",
* "default": 99.99
* },
* "statusLevel": {
* "type": "string",
* "enum": ["optimal", "degraded", "critical"],
* "default": "optimal"
* }
* },
* "providesContext": {
* "agentic-lab/statusLevel": "statusLevel"
* },
* "usesContext": [
* "postId",
* "postType",
* "agentic-lab/environmentMode"
* ],
* "supports": {
* "html": false,
* "align": ["wide", "full"],
* "interactivity": {
* "clientNavigation": true,
* "interactive": true
* },
* "color": {
* "background": true,
* "gradients": true,
* "text": true
* },
* "spacing": {
* "padding": true,
* "margin": ["top", "bottom"],
* "blockGap": true
* },
* "typography": {
* "fontSize": true,
* "lineHeight": true
* },
* " '__experimentalBorder' -> border ": {
* "radius": true,
* "width": true,
* "color": true
* },
* "shadow": true
* },
* "editorScript": "file:./index.js",
* "editorStyle": "file:./index.css",
* "style": "file:./style-index.css",
* "viewScriptModule": "file:./view.js",
* "render": "file:./render.php"
* }
*/
Визначте строгі типи (string, number, boolean, object, array), дефолтні значення та допустимі списки enum без використання крихких DOM-селекторів source.
Замість створення кастомних контролів відступів, меж і палітр активуйте color, spacing, typography, border та shadow — вони автоматично зв'яжуться з theme.json v3.
Залиште React-залежності суворо в editorScript, а для фронтенду підключіть легкий нативний ES-модуль через viewScriptModule.
Запустіть wp-scripts build --blocks-manifest для генерації єдиного файлу blocks-manifest.php і підключіть його через wp_register_block_types_from_metadata_collection().