Редактор блоков WordPress. 2 часть - создаём первый блок
Какие бы стандартные блоки не давал новый WordPress редактор блоков (Gutenberg) в комплекте - но под каждый сайт требуются не стандартные блоки, а кастомные. Можно конечно под проект стилизовать имеющиеся - просто подкорректировав их стили. Но мы пойдем дорогой трудной, дорогой не прямой...
Навыки, необходимые для этого урока:
Понимание API WordPress
Умение написания простого плагина вордпресс
Базовые знания php и js
В этом уроке:
Создадим свой первый блок:
Gutenberg в wordpress - как работать? Здесь и найдёте ответ!
Как я и обещал - первые блоки мы будем создавать без особых инструментов для этого, и без специально настроенного окружения. Если вы работаете в IDE - отлично. Но если юзаете блокнот в клеточку типа notepad++ или его младшего собрата sublime - на первое время хватит и их.
Также примеры будут на ES5, никакого ESNext или JSX. Что это и как это - мы разобрали в прошлом уроке. Создать простой блок можно и без них. Главное - уловить концепцию написания блока. Простые шаги, чтобы в js-файле его зашевелить под гутенберг (блочный редактор вордпресс).
Этот урок будет целостным и законченным. Этакий Hello World.
Содержание:
Структура проекта:
Создаем новый проект. Я его назвал: OtFm First Block
Повторяем структуру и пустые файлы как на скриншоте выше.
otfm-first-block.php
будет содержать регистрацию и подключение css и js файлов
index.php
- пустой файл-заглушка.
Папка first-block содержит 2 файла:
block-style.css
- файл стилей блока. Необходим и в редакторе блоков, и в фронтенде.
index.js
- наш первый блок. Необходим только в редакторе.
PHP файл:
Заголовки плагина
В файле otfm-first-block.php
добавляем заголовки плагина
<?php
/*
Plugin Name: OtFm First Block
Description: First Block for WordPress 5 block editor
Version: 1.0.0
Author: Otshelnik-Fm (Wladimir Druzhaev)
Author URI: https://otshelnik-fm.ru/
*/
if (!defined('ABSPATH')) exit; // Game over
На 9-й строке запрещаем прямой просмотр php файла - если сервер это вдруг позволяет сделать.
Плагин готов - активируем.
Регистрация блока и ресурсов
Следующим шагом нам надо зарегистрировать наши стили и скрипт. И на уровне php зарегистрировать новый блок, подключив к нему js и css файл.
Делаем это в одной функции:
add_action('init', 'otfm_fb_load');
function otfm_fb_load(){
// регистрируем стиль
wp_register_style(
'otfm_fb_style',
plugins_url( 'first-block/block-style.css', __FILE__ )
);
// регистрируем скрипт
wp_register_script(
'otfm_fb_script',
plugins_url( 'first-block/index.js', __FILE__ ),
array( 'wp-blocks', 'wp-element' ),
filemtime( plugin_dir_path( __FILE__ ) . 'first-block/index.js' )
);
// не WordPress 5.0
if( !function_exists( 'register_block_type' ) ) return;
// регистрируем блок
register_block_type( 'otfm-first/first-block', array(
'editor_script' => 'otfm_fb_script', // подключаем скрипт в админке
'editor_style' => 'otfm_fb_style', // подключаем стиль в админке
'style' => 'otfm_fb_style' // подключаем стиль в фронтенде
) );
}
Функция висит на хуке init. Внутри функции 4-ре логические секции:
1. Регистрируем стиль
2. Регистрируем скрипт
3. Проверяем что это ВП 5.0
4. Регистрируем блок
Рассмотрим подробней:
1. Регистрация стиля (4-я строка) - ничего необычного. Знакомая нам ВП функция.
2. При регистрации скрипта (10-я строка, тоже стандартная ВП функция), но стоит обратить внимание на зависимости (13-я строка). WordPress скрипты разбиты на packages (пакеты) - зависимости, которые вызываются до загрузки нашего блока. Чтобы не тянуть весь бандл со всеми пакетами - их и разбили на мелкие части. И в вордпресс 5.0, при работе с блоками, необходимо точно определять зависимости. В противном случае вы получите в консоли ошибку undefined скрипта.
array( 'wp-blocks', 'wp-element' ),
- это минимальные зависимости для создания блока. Здесь вы найдете их handle.
Ну и собственно описание всех пакетов в этом справочнике
где:
wp-blocks
- это библиотека JavaScript в вордпресс, которая обрабатывает регистрацию блоков и связанные с ними функции.
wp-element
– библиотека, которая обрабатывает пользовательский интерфейс блока (block UI).
3. Если кто-то в WordPress ниже 5.0 версии запустит наш плагин - не появится fatal error из-за несуществующей функции на 21-й строке. Если вы блок регистрируете через хук init
- обязательно делайте такую проверку (18-я строка).
4. На 21-й строке мы регистрируем наш первый блок.
Первым аргументом функция принимает имя блока. Чтобы не было конфликтов - используется соглашение в виде пространства имён: otfm-first/first-block
Вторым аргументом функция register_block_type()
принимает массив (необязательно):
array(
'editor_script' => '',
'editor_style' => '',
'script' => '',
'style' => '',
'render_callback' => ''
)
- editor_script – handle скрипта, который загружается только в редакторе.
- editor_style – handle стилевого файла, который загружается только в редакторе.
- script – handle скрипта, который загружается только в фронтенде.
- style – handle стилевого файла, который загружается только в фронтенде.
- render_callback - коллбек функция, для создания динамических блоков с помощью не js, а php
editor_script
, editor_style
и style
мы и использовали выше, подключив скрипт и стиль для редактора Gutenberg блоков. И стиль для фронтенд стилизации блока.
Проверим загрузку наших ресурсов - открыв создание поста:
- при создании записи стиль и скрипт загружаются. А посмотрев в фронтенде - мы увидим, что там загрузился только стиль. В общем заготовка работает.
Еще вариант подключения ресурсов
Ещё один вариант подключения скриптов и стилей - ВП 5.0 вводит для этого еще 2 хука:
enqueue_block_editor_assets
- хук срабатывает в редакторе блоков (по сути - в админке)enqueue_block_assets
- хук срабатывает везде где есть блоки (и сам редактор и в фронтенде - где выводится блок)
т.е. вы можете скрипт и/или стиль не предавать в массиве register_block_type()
, а написать свою функцию с подключением скрипта и стиля (wp_enqueue_style()
и wp_enqueue_script()
) и вешать на эти хуки. И их область подключения будет определена только в том месте, где эти хуки срабатывают.
Тут нет единого мнения - кто-то делает так, кто-то по другому. Все варианты правильные.
С php файлом мы закончили.
CSS файл:
В наш стилевой файл block-style.css внесем следующие стилевые правила:
.otfm_fb_text {
background-color: #a0db91;
border: 1px solid #6da270;
color: #3a407e;
font-size: 16px;
line-height: normal;
margin: 5px 0;
padding: 12px;
}
- обычная стилизация простого блока. Эти стили, напомню, мы подключили и в редакторе и в фронтенде.
JS файл:
Окунёмся в мир js и чудный мир блоков!
Полный код блока
Вписываем этот код в index.js файл:
( function( blocks, element ) {
var el = element.createElement;
blocks.registerBlockType( 'otfm-first/first-block', {
title: 'Первоблок',
description: 'Описание блока в сайдбаре',
icon: 'universal-access-alt', // dashicons
category: 'layout', // category of the block
keywords: [ // search sinonime block
'первоблок',
'otfm'
],
edit: function() {
return el(
'p',
{ className: 'otfm_fb_text' },
'Текст блока в редакторе'
);
},
save: function() {
return el(
'p',
{ className: 'otfm_fb_text' },
'Сохраненный текст в фронтенде :-D'
);
}
}); // END registerBlockType
}(
window.wp.blocks,
window.wp.element
) );
- глобально наш код состоит из 2-х фрагментов:
В первом мы определяем переменные
Во втором мы регистрируем блок.
Смотрите на принт ниже:
Итак:
В нашу анонимную функцию мы передаем window.wp.blocks
и window.wp.element
- именно их мы и указали в зависимостях в php файле.
Внутри нашей функции мы определили переменную el
(2-я строка js-кода) из element.createElement - она отвечает за создание тега. Теперь она создает простой тег (p - параграф в нашем случае), или использует компоненты - например RichText (это может быть RichText, BlockControls AlignmentToolbar, ColorPalette и т.д.)
Посмотрим на 15-ю строку:
в функции редактирования мы и создаем тег p
через el
Это эквивалентно такой записи:
edit: function() {
return wp.element.createElement(
'p',
{ className: 'otfm_fb_text' },
'Текст блока в редакторе'
);
},
- но чтобы код был компактный и следуя принципам DRY (Don't repeat yourself - не повторяйся) - его сократили, загнав метод создания элемента в переменную. Когда внутри js много html тегов - это упрощает создание тега. Здесь и вступает в работу библиотека React.
Функция создания блока
Давайте перейдем к функции создания блока.
Создаем блок через функцию registerBlockType()
Эта функция первым аргументом (4-я строка) получает имя блока (строка), тот namespace - пространство имен, что мы определили регистрируя блок через php.
Второй аргумент - объект конфигурации (настроек) блока. В него входят атрибуты, функция редактирования и функция сохранения.
Что же там внутри объекта:
title - заголовок блока.
description - описание блока, которое появляется справа (сайдбар "Настройки", он же "Инспектор")
icon - имя dashicon или svg иконка. В следующих уроках расскажу как добавить svg иконку.
category - категория, в которую попадет блок.
Gutenberg (редактор блоков) зарегистрировал такие:
"common" - основные блоки
"formatting" - форматирование
"layout" - элементы разметки
"widgets" - виджеты
"embed" - вставки
keywords - массив ключевых слов для поиска. Блочный редактор предоставляет удобный механизм поиска блоков:
По иконке "Плюс" вы открываете меню выбора блока - там доступен и поиск блоков.
Или в пустом блоке нажимаете /ключевое-слово
- более быстрый механизм поиска блоков по ключам.
В массиве keywords допускается вписать 3 значения. Но это не значит что всего 3 синонима для поиска вы задать можете. Можно все слова вписать в одну строку - например так:
keywords: [
'otfm первоблок ещё слово'
],
- т.е. ограничений на слова нету. По всем этим словам редактор блоков будет искать. Причем он начинает поиск с вводом первых букв слова.
С основными настройками для нашего блока мы разобрались.
Описание всех настроек registerBlockType():
title
(строка): имя в редактореdescription
(не обязательно. строка): описывает назначение блокаicon
(не обязательно. Dashicon или JS element): иконка блокаcategory
(строка): категория блокаkeywords
(не обязательно. массив): до трёх ключевых слов поиска блокаattributes
(не обязательно. объект): доп атрибуты - обрабатывает данные динамического блокаedit
(функция): функция, которая возвращает разметку для визуализации в редактореsave
(функция): функция, которая возвращает разметку, которая будет отображена в фронтендеsupports
(не обязательно. объект): определяет поддерживаемые блоком функцииstyles
(не обязательно. массив): определяет вариации стилейtransforms
(не обязательно. массив): правила преобразования блока в другие блокиparent
(не обязательно. массив): блок может быть зависим от других блоков. Указывается родительский блок
Дополнительно давайте опишем вкратце supports опцию:
Свойство support принимает объект с логическими значениями, чтобы определить, поддерживает ли ваш блок определенные основные функции.
Например так:
supports:{
multiple: false // запретить добавление блока более одного раза (например тег "Далее")
},
скажет редактору блоков что наш блок можно в контенте записи использовать только один раз. Например тег "More" в вордпресс - его глупо использовать дважды.
Ознакомьтесь с ними в руководстве по блокам
Рассмотрим styles:
- это дополнительные стили. Или BSV - block style variation (вариации стиля блока)
styles: [
// обозначим по умолчанию.
{
name: 'default',
label: 'Квадратный',
isDefault: true
},
{
name: 'round',
label: 'Круглый'
}
],
- это позволит вам задать дополнительные стили, а потом на уровне css стилизовать ваш блок. В первой части мы рассматривали как это выглядит визуально.
Edit & Save
Перейдем к функции edit
на 14-й строке:
В документации edit
и save
описаны здесь
Это уровень абстракции поверх react. В этой функции мы видим в реальном времени все наши изменения в редакторе блоков.
В нашем коде мы создаем элемент параграфа. Задаём дополнительный css класс блоку - чтобы в css файле написать для него стили. И задаем неизменяемый текст для параграфа. На этом с редактированием всё.
Перейдем к функции save
на 22-й строке:
Здесь нам надо повторить всю верстку как и в функции edit. В данном случае они идентичны, за исключением текста в параграфе. Именно этот блок отобразится у нас в фронтенде.
Эти две функции принимают props
- опции состояния. Примерно так:
edit: function( props )
- но т.к. в этом уроке мы не использовали стилизацию или динамические данные - этого в примере нет. Это будет рассмотрено в последующих уроках.
Создание блока в общих чертах
Если рассматривать в общих чертах создание блока - то вот вид очень простого блока на jsx:
registerBlockType(
'otfm-first/first-block',
{
title: 'Первоблок',
icon: 'universal-access-alt',
category: 'layout',
keywords: ['первоблок','otfm'],
edit: () => <h2>Welcome to the Gutenberg Editor!</h2>,
save: () => <h2>How am I looking on the front end?</h2>
}
);
- этот пример дан, чтобы вы лучше представляли структуру блока, когда уже прочитали столько нового. Здесь мы пропустили необязательные параметры - вроде описания блока, атрибуты и прочее.
Блок создан - его вид, внутри, в БД:
Итак: мы познакомились с примером создания блока. Вы этот код можете сохранить и он уже будет работать в вашем редакторе блоков:
В фронтенде наш блок отличается только текстом, как и задумано:
Посмотрим вёрстку блока - стандартные классы и наш дополнительный что мы задали:
WordPress 5.0 редактор блоков даёт классы по такому шаблону:
wp-block-/namespaces/
т.е. у на будет wp-block-otfm-first-first-block
В базе данных - в таблице wp_posts запишутся такие данные в публикацию:
<!-- wp:otfm-first/first-block -->
<p class="wp-block-otfm-first-first-block otfm_fb_text">Сохраненый текст в фронтенде :-D</p>
<!-- /wp:otfm-first/first-block -->
Но как мы видели скриншотом выше - html комментарии из исходного кода парсер вордпресса вычищает и они не попадают в исходный код страницы.
Что дальше?
Мы создали простой статичный блок. Рассмотрели регистрацию css/js и зависимости при их регистрации. Зарегистрировали блок и задали его первоначальную конфигурацию. Это первые шаги в программирование под новый редактор блоков.
В следующем уроке мы создадим блок, который будем развивать и дополнять, изучая новые возможности блочного редактора.
Здесь было очень много ссылок на хэндбук Gutenberg редактора (gutenberg wordpress documentation - ещё раз) - как видите официальная документация там в порядке. Наверно надо немного привыкнуть к ней - и тогда вы с лёгкостью сможете в ней искать нужные ответы. Документация улучшается. А следить за её обновлением нужно конечно через гитхаб - работа ведется регулярно.
В первой части я упомянул про инструмент create-guten-block и если вы уже созрели - предлагаю попробовать его. Т.к. создавать новый блок с ноля несколько тоскливо - надо регистрировать блок, скрипты и стили в php. Потом в js - каркас блока вставить (а для этого подойдут макросы или горячие клавиши на создание каркаса в js-файле внутри вашей ide) - несколько скрупулёзное занятие.
Если вы работаете через WP-CLI - у них есть поддержка блоков: команда для создания такого каркаса.
Ещё один источник и "подглядеть" можно в самом вордпресс. На гитхабе список реализованных в вордпрессе блоков вы найдете по этой ссылке
Ну как? Сложно создать первый блок?
Какие трудности у вас были и какие впечатления вы испытали от своего первого гутенберг блока?
- делитесь в комментариях!
Добавил упущенную настройку styles - вариации стилей блока (BSV)
Спасибо, все очень подробно расписано, перехожу к следующему уроку)