Редактор блоков WordPress. 3 часть - добавляем кнопку в RichText редактор
В этом руководстве я покажу как добавить свою произвольную кнопку в редактор блоков вордпресс 5.0. А именно: кнопку в RichText редактор (Gutenberg редактор)
В 1-й части мы рассмотрели его анатомию - это простой редактор с кнопками. Вверху содержится BlockToolbar, а уже в нём элементы внутреннего форматирования (inline formatting).
Сейчас там 4-ре кнопки: выделение жирным, курсивом, ссылка и перечеркнутый текст. Вот как это выглядит сейчас:
Но мы добавим нужную кнопку выделяющую однострочный код - <code>
. И получится так:
А поняв принцип - вы сможете добавлять любые свои кнопки в гутенберг редактор: хоть в span
оборачивать и выделать цветом, хоть тег small
, sub
, sup
. Всё будет в ваших руках.
Добавление кнопки - тоже работа с js кодом. Но никаких регистраций блока не потребуется - на стороне php все будет очень просто.
Поехали!
Добавим кнопку:
Механизм работы с кнопками в внутреннем форматировании названы Format API (API форматирования). Он позволяет указать тег, которым можно оборачивать текст и настройки для тего.
php-файл
Давайте в нашем php файле зарегистрируем наш скрипт:
add_action('enqueue_block_editor_assets', 'otfm_load_code_bttn');
function otfm_load_code_bttn(){
wp_enqueue_script(
'othb_code',
plugins_url( 'src/code-bttn/index.js', __FILE__ ),
array( 'wp-element', 'wp-rich-text', 'wp-editor' )
);
}
Обратите внимание на массив зависимостей - т.к. эти пакеты использовать будем внутри скрипта.
Перейдём к index.js - javascript файлу, в котором опишем нашу кнопку.
Функция registerFormatType()
Вся работа идет внутри функции registerFormatType()
Функция находится по пути /packages/rich-text/src/register-format-type.js
. Первым аргументом принимает строку - имя. Вторым - объект настроек.
Объект настроек:
- tagName: строка. Этот HTML-тег обернет выделение.
- className: строка || null. HTML-класс назначенный тегу.
- title: строка. Имя.
- edit: функция. Должен возвращать компонент для взаимодействия пользователя с новым зарегистрированным форматом.
При создании своих span тегов полезна будет настройка className
- по этому классу вы сможете стилизовать через css свои теги. Можно выстроить заранее определённые выделения внутреннего текста - и оно будет стандартизировано для вашего сайта.
js-файл
Добавим кнопку, которая будет оборачивать выделенный текст в тег <code>
Добавим в index.js:
(function (richText, element, editor) {
var el = element.createElement,
fragment = element.Fragment;
var registerFormatType = richText.registerFormatType,
unregisterFormatType = richText.unregisterFormatType,
toggleFormat = richText.toggleFormat;
var richTextToolbarButton = editor.RichTextToolbarButton,
richTextShortcut = editor.RichTextShortcut;
var type = "core/code";
unregisterFormatType(type);
registerFormatType(type, {
title: "Code",
tagName: "code",
className: null,
edit: function edit(props) {
var isActive = props.isActive,
value = props.value,
onChange = props.onChange;
var onToggle = function() {
return onChange(toggleFormat(value, { type: type }));
};
return el(
fragment,
null,
el(richTextShortcut, {
type: "access",
character: "x",
onUse: onToggle
}),
el(richTextToolbarButton, {
icon: "editor-code",
title: "Code",
onClick: onToggle,
isActive: isActive,
shortcutType: "access",
shortcutCharacter: "x"
})
);
}
});
}(
window.wp.richText,
window.wp.element,
window.wp.editor
));
На первой строке мы получаем наши зависимости.
Потом определяем переменные.
На 15-й строке функция registerFormatType()
- задаём ей тайтл, имя тега с которым будем работать и html-класс нам не нужен - null.
Далее функция edit()
- определяем переменные и в onChange
происходит переключение - оборачиваем в наш тег или снимаем выделение.
На 36-й строке задаем настройки для тулбара:
мы задаем иконку dashicons - 37 строка.
title - для всплывающей подсказки
в shortcutCharacter выставляем сочетание горячих клавиш. В коде стоит "x" - значит что по комбинации "Shift + Alt + X" выделенный участок мы обернем в тег <code>
На этом простое добавление кнопки завершено. Результат:
css стили для тега <code>
впишите свои.
Замечание и полезные ссылки:
Стоит отметить, что в консоли вы увидите ошибку уведомление сгенерированное самим редактором:
Format "core/code" is already registered. rich-text.min.js:1:10782
визуально:
В обсуждении говорят что можно расслабиться. Если вы знаете больше подробностей - дайте мне знать. Я не задавал им вопрос - в чём дело и не углублялся в решение. На работу это сообщение не влияет - просто мессадж от разработчиков, а не консольная ошибка.
upd: Мы с Михаилом Кобзарёвым нашли причину - если при регистрации скрипта подключить его в подвале, то сообщение из консоли исчезает.
Вот пример итогового php:
add_action('enqueue_block_editor_assets', 'otfm_load_code_bttn');
function otfm_load_code_bttn(){
wp_enqueue_script(
'othb_code',
plugins_url( 'src/blocks/code-bttn/index.js', __FILE__ ),
array( 'wp-element', 'wp-rich-text', 'wp-editor' ),
filemtime( dirname( __FILE__ ) . '/src/blocks/code-bttn/index.js' ),
true
);
}
Документация по Format API только пишется.
Посмотреть вы можете здесь. Описании функций доступно будет в компоненте RichText или в туториалах: docs/designers-developers/developers/tutorials/format-api/
. над черновиком работа ведётся тут или здесь
Готовое решение для выделения кнопками: code
, sub
, sup
вы найдете здесь: advanced-rich-text-tools или в официальном репозитории WordPress
p.s. Спасибо Михаилу Кобзарёву за тестирование данного кода и выявление ошибки. Отсутствие в коде unregisterFormatType(type);
приводило к отсутствию кнопки. Обратите на это внимание - если у вас кнопка не появлялась
Добрый день, Владимир.
Спасибо за полезные статьи. Побольше бы таких.
Если не затруднит и найдете время ответить (а может это будет идеей для следующей статьи):
возникла необходимость добавлять параметры к существующим блокам, при изменении которых на блок вешается дополнительный класс, по которому данный блок потом стилится.
Добавить поле с параметром получилось, а вот с функцией (объектом) save загвоздка - не дает модифицировать свойство
element.props.className
Пример кода:
Т.е. в
attributes.alter_height
содержится нужное значение, но element.props.className не меняется.Можно ли как-то изменить класс возвращаемого объекта, не создавая объект заново - блоки бывают довольно сложной структуры и не хочется ее заново пересоздавать
Заранее спасибо за Ваше время.
Здравствуйте.
Похожий пример в документации https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#editor-blocklistblock - это не работает?
Спасибо большое. Да, этот пример помог.
А я пытался изменить класс прямо в обработчике события editor.BlockEdit, в котором добавлял поля для дополнительного параметра в редакторе