Как создать свой блок в Gutenberg - новом редакторе для WordPress. Разбираемся на живом примере.
Upd [16.02.2020]
Плагин - констуктор блоков: https://wordpress.org/plugins/lazy-blocks/
Upd [27.12.2018]:
Появился плагин для WP с функционалом добавления блоков: https://getblocklab.com/
Начиная с 5 версии Wordpress стандартный текстовый редактор заменят на Gutenberg. Обзор редактора, его плюсы и минусы можете найти в интернете. А мы сегодня будем расширять его функционал, добавляя свой блок.
Создание блоков и их отображение прописывается в js и css файлах. Но для того чтобы все корректно работало необходимо их правильно подключить.
Для добавления своего блока в Wordpress я добавил в папку с текущей темой новую папку my_gutenberg и в неё скрипт init_my_custom_gutenberg_block.php, который в свою очередь подключил в functions.php.
Структура файлов получилась следующая (относительно папки с темой):
|- my_gutenberg/
|- init_my_custom_gutenberg_block.php
|- my_first_block/
|- script_editor.js
|- style_editor.css
|- style.css
Содержимое init_my_custom_gutenberg_block.php представлено ниже:
function my_custom_block_for_gutenberg() {
wp_register_script(
'mcbfg_script_editor',
get_template_directory_uri() . '/my_gutenberg/my_first_block/script_editor.js',
array( 'wp-blocks', 'wp-element', 'wp-components' )
);
wp_register_style(
'mcbfg_style_editor',
get_template_directory_uri() . '/my_gutenberg/my_first_block/style_editor.css',
array( 'wp-edit-blocks' )
);
wp_register_style(
'mcbfg_style',
get_template_directory_uri() . '/my_gutenberg/my_first_block/style.css',
array( 'wp-blocks' )
);
register_block_type( 'my-gutenberg/my-first-block', array(
'editor_script' => 'mcbfg_script_editor',
'editor_style' => 'mcbfg_style_editor',
'style' => 'mcbfg_style'
) );
}
add_action( 'init', 'my_custom_block_for_gutenberg' );
На хук init вешается функция которая подключит все неоходимые файлы в редакторе и на выводе во фронтальной части для нашего блока.
Подключение стилей и скриптов осуществляется как обычно с помощью wp_enqueue_style() и wp_enqueue_scripts(). Но с одной особенностью, а именно необходимо указать правильные зависимости.
Для скриптов в режиме редактирования:
array( 'wp-blocks', 'wp-element', 'wp-components' )
Для стилей в режиме редактирования:
array( 'wp-edit-blocks' )
Для стилей в режиме редактирования и во фронтальной части:
array( 'wp-blocks' )
После подключения стилей и скриптов необходимо вызвать функцию register_block_type() для их инициализации в Gutenberg, передав массив параметров:
- editor_sctipt - скрипт для редактора (именно в нем и происходит добавление нового блока)
- editor_style - стили для редактора
- style - стили для фронтальной части
Очередность подключения стилей в режиме редактирования следующая:
1. style
2. editor_style
То есть правила записанные в editor_style имеют больший приоритет, чем правила в style.
Чтобы создать новый блок, нам необходимо зарегистрировать его с помощью Gutenberg, вызвав registerBlockType(). Делать это следует в подключаемом JS файле:
registerBlockType(
'block-namespace/block-name',
{
// параметры создаваемого блока
}
);
Пример нашего первого блока:
var el = wp.element.createElement,
registerBlockType = wp.blocks.registerBlockType,
RichText = wp.editor.RichText;
registerBlockType( 'my-gutenberg/my-first-block', {
title: 'My First Block',
description: 'Description',
icon: {
background: '#7e70af',
foreground: '#fff',
src: 'format-aside',
},
attributes: {
content: {
type: 'array',
source: 'children',
selector: 'p',
}
},
category: 'common',
edit: function( props ) {
var content = props.attributes.content;
function onChangeContent( newContent ) {
props.setAttributes( { content: newContent } );
}
return el(
RichText,
{
tagName: 'p',
className: props.className,
onChange: onChangeContent,
value: content,
}
);
},
save: function( props ) {
var content = props.attributes.content;
return el( RichText.Content, {
tagName: 'p',
className: props.className,
value: content
} );
},
} );
Список параметров:
- title (строка): отображается в редакторе в качестве метки блока поиска
- description (необязательная строка): описывает назначение блока
- icon (дополнительный элемент Dashicon или JSX): значок, связанный с блоком
- category (строка): где блок появляется в диалоговом окне "Добавить блоки"
- keywords (необязательный массив): до трех ключевых слов, используемых в поиске по блокам
- attributes (необязательный объект): обрабатывает данные динамического блока
- edit (функция): функция, возвращающая разметку для рендеринга в редакторе
- save (функция): функция, которая возвращает разметку для отображения во фронтальной части сайта
- useOnce (необязательный логический тип): запретить добавление блока более одного раза
- supports (необязательный объект): определяет поддерживаемые блоком функции
title - заголовок блокаПри вставке или поиске блока в редакторе заголовок будет отображаться в списке доступных блоков.
Он также отображается в окне настроек текущего блока вместе с описанием, если оно определено. Если окно настроек текущего блока не отображается, вы можете использовать значок шестеренки в правом верхнем углу редактора Gutenberg для переключения отображения.

description - описание блокаОтображается в окне настроек текущего блока.

icon - иконка блокаИконка блока, которая может быть выбрана из списка dashicons самого wordpress или иметь запись JSX формата, что позволит использовать любую SVG иконку (убедитесь, что она соответствует размеру остальных иконок - 20x20).
Стоит отметить, что если вы выбираете иконку из dashicons, то записывать значение в передаваемый параметр нужно без dashicon-, например для иконки dashicons-format-aside запись будет вида: format-aside.
![]()
Значением может быть объект, в котором заданы свойста background и foreground, для указания фонового цвета и цвета иконки.
icon: {
background: '#7e70af',
foreground: '#fff',
src: 'format-aside',
}
![]()
category - категория блокаВ настоящий момент доступны следующие категории:
- common - Основные блоки
- formatting - Форматирование
- layout - Элементы разметки
- widgets - Виджеты
- embed - Вставки
keywords - ключевые слова для поискаДля того, чтобы блок можно было проще найти, можно указать до трех ключевых слов. Лучше всего выбирать ключевые слова, которые тесно связаны с функциональностью нашего блока. И хотя добавление ключевых слов является необязательным, это отличный способ облегчить пользователям поиск наших блоков.
attributes - атрибуты блокаАтрибуты блока являются необязательным параметром, т.к. для простых статичных блоков они не понадобятся. Однако, когда нужны динамические данные - без атрибутов не обойтись.
attributes: {
cover: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src',
},
author: {
type: 'string',
source: 'children',
selector: '.book-author',
},
pages: {
type: 'number',
},
},
Параметр типа определяет с какими данными вы будете иметь дело. Это может быть array, string, number, object, url или любой другой тип из руководства ReactJS
Данные в Gutenberg хранятся в виде HTML (за исключением мета данных) и для правильной работы с ними необходимо правильно их описать, а именно указать как будут извлекаться данные для обработки из хранимого HTML в редактируемый. Сам механизм работает на основе библиотеки hpq
attribute - для извлечения значений из атрибутов html тегов (например: src для img)text - для извлечения внутреннего текста из разметкиhtml - для извлечения внутреннего HTML кода из разметкиchildren - для извлечения дочерних элементов в виде массива виртуальных элементов (например: для извлечения элементов p из RichText)query - для извлечения данных из разметки в виде массива в соответсвии с заданным запросом (например: извлечь все src и alt атрибуты из тегов img){
images: {
source: 'query'
selector: 'img',
query: {
url: { source: 'attribute', attribute: 'src' },
alt: { source: 'attribute', attribute: 'alt' },
}
}
}
// {
// "images": [
// { "url": "https://lorempixel.com/1200/800/", "alt": "large image" },
// { "url": "https://lorempixel.com/50/50/", "alt": "small image" }
// ]
// }
meta - для извлечения данных из мета данных записи, таких как: автор, дата публикации и пр.editПараметр edit описывается с помощью функции:
edit: function( props ) {
// тело функции
}
Данная функция отвечает за отображение нашего блока при редактировании записи. Детальное рассмотрение.
saveПараметр save также, как и edit описывается с помощью функции:
save: function( props ) {
// тело функции
}
Данная функция отвечает за формирование хранимого и отображаемого HTML кода. Детальное рассмотрение.
useOnceЭто полезное свойство, которое позволяет вам блокировать добавление блока более одного раза на страницу. После добавления блока значок блока отображается серым цветом и не может быть выбран. По умолчанию useOnce имеет значение false.
supportsОпределяет какие особенности имеет наш блок. Значения задаются в логическом типе данных.
- align (по умолчанию: false)
свойство добавляет элементы управления блоком, которые позволяют изменять выравнивание блока. Важно: не работает с динамическими блоками.
- alignWide (по умолчанию: true)
Gutenberg позволяет включить выравнивание по ширине для вашей темы. Чтобы отключить это поведение для одного блока, установите для этого флага значение false.
- anchor (по умолчанию: false)
Якоря позволяют напрямую ссылаться на конкретный блок на странице. Это свойство добавляет поле для ввода идентификатора для блока и кнопки для копирования прямой ссылки.
- customClassName (по умолчанию: true)
Это свойство добавляет поле для определения пользовательского ClassName для оболочки блока.
- className (по умолчанию: true)
По умолчанию Gutenberg добавляет класс с формой .wp-block-your-block-name к корневому элементу вашей сохраненной разметки. Это помогает создать согласованный механизм для стилизации блоков, на которые могут влиять темы и плагины. Если по какой-либо причине класс не нужен в разметке, эта функция может быть отключена.
- html (по умолчанию: true)
По умолчанию Gutenberg позволит редактировать разметку блока отдельно. Чтобы отключить это поведение, установите html в false.
- inserter (по умолчанию: true)
По умолчанию все блоки появятся в вставке Gutenberg. Чтобы скрыть блок, чтобы его можно было вставлять только программно, установите inserter равным false.
- multiple (по умолчанию: true)
Немножественный блок может быть вставлен в каждый пост, только один раз. Например, встроенный блок «More» не может быть вставлен снова, если он уже существует в редактируемом сообщении. Значок немножественного блока автоматически затемняется, чтобы предотвратить добавление несколько экземпляров.
edit и save