Drupal 10 добавил в ядро модуль wysiwyg CKEditor 5. Т.е. уже из «коробки» у вас есть редактор html кода.
API CKEditor 4 и 5 версий значительно отличаются, потому все проекты добавляющие кнопки и функционал в CKEditor 4, который можно установить как contrib модуль и в Drupal 10, не работают для CKE 5й версии.
Именно одна из таких задач переделки плагина с 4 версии на 5ю у меня и возникла.
Для конкретики, я буду рассматривать именно свой опыт — плагин c5bb (CKEditor 5 Bootstrap Buttons) опубликован на drupal.org, можете скачать исходники от туда.
Что делает плагин:
- Добавляет инструмент для редактирования ссылок типа <a class = «btn» >, считая их бутстраповскими кнопками.
- Позволяет выбрать ряд настроек для кнопки-ссылки, а также добавить в тело кнопки коды иконок коллекций fontawesome и glyphon. Т.е. все те же фичи, что предоставлял плагин для 4й версии CKEditor — ckeditor_bootstrap_buttons.
В итоге, в HTML формируется структура вида (демонстрация максимально расширенной версии) :
1 2 3 4 5 6 7 |
<a class="btn btn-light-primary btn-sm" href="#" target="popup"> <em class="fa fontawesome-icon-left fa-arrow-left"></em> <span class="bs-icon-left glyphicon glyphicon-pencil"></span> <span class="text">A Button</span> <span class="bs-icon-right glyphicon glyphicon-pencil"></span> <em class="fa fontawesome-icon-left fa-arrow-right"></em> </a> |
Задача объёмная и состоит из двух блоков: Drupal и CKE Plugin.
Позднее я добавлял также конфигурирование плагина через админ интерфейс.
DRUPAL часть
Кроме стандартных вещей, добавления зависимости модуля от ckeditor5, модуль должен объявить плагин CKE. Это можно сделать разными путями, через аннотацию, создания плагина в каталоге /src и описания через module.ckeditor5.yml файл.
Какие то вещи можно выполнить только одним путём, какие то могут выполнятся разными способами. Т.к. в моём плагине нет нужны в настройках конфигурации, то я могу всю друпальную часть ограничить объявлениями через yml файл.
c5bb.ckeditor5.yml файл
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
c5bb_bbutton: ckeditor5: plugins: - bbutton.BButton drupal: label: Bootstrap Buttons library: c5bb/buttons admin_library: c5bb/admin.styles # Toolbar button. toolbar_items: BButton: label: Bootstrap Buttons elements: - <a> - <a class href target> - <em class> - <span> - <span class> |
Этот файл монтирует ваш плагин (js code для CKE 5 API) в экосистему Drupal, делая его доступным для установленного CKE 5 и настроек текстовых форматов.
Следующая строка имеет формат — «имя каталога плагина» . «имя JS класса».
1 |
- bbutton.BButton |
В секции настроек drupal нужно указать имя билда библиотеки плагина — library (объявлена в c5bb.libraries.yml) и можно указать библиотеку — admin_library, которая подключается на странице администрирования (настройки текстовых форматов).
c5bb.libraries.yml файл
1 2 3 4 5 6 7 8 9 10 |
buttons: js: js/build/bbutton.js: { preprocess: false, minified: true } dependencies: - core/ckeditor5 admin.styles: css: theme: css/admin-styles.css: { } |
В моем случае библиотека для админки включает в себя только небольшой файл стилей, который определяет картинку для иконки в инструментах.
И очень важная секция ckeditor5.yml описателя — elements.
1 2 3 4 5 6 |
elements: - <a> - <a class href target> - <em class> - <span> - <span class> |
Запись <a> — означает, что плагин может самостоятельно создавать тег <a>, тогда как <a class href target> — показывает, что плагин может задавать атрибуты «class href target» к существующему тегу <a>. Если не укажите отдельно <a>, то валидатор при настройке инструментов wysiwyg будет требовать, чтобы ваш или какой то другой плагин «умел» создавать теги <a>.
Такой плагин есть в наборе — это Link (инструмент ссылка в CKE 5). Не указав <a> в elements, вы не сможете добавить кнопку вашего плагина без Link (или иного плагина, что умеет создавать <a>) в панель инструментов.
Тоже касается и <em>, который как видите не добавлен в текущей версии, но его надо будет добавить, чтобы не зависеть от инструмента Italic.
CKE Plugin часть
Эта может требовать некоторых hard скилов, таких например как работу с npm и ts (typescript).
Билд плагина (сборка js кода) выполняется с из папки модуля. В корне модуля вы найдете файлы package.json и webpack.config.js.
Они практически одинаковы для любых ваших проектов, если вы не отступаете от принятой структуры CKE5 плагина в экосистеме Drupal.
Установите npm (npm i).
И далее можно будет собирать плагин командой npm run build или запустить слежение для автобилда при изменениях в коде — npm run watch.
При билде создаётся папка /js/build, где будут сборки всех ваши плагинов из каталога /js/ckeditor5_plugins.
Т.е там может быть вообще то несколько плагинов. У каждого плагина должен быть свой файл /src/index.js
Сборщик здесь не умеет работать с ts, т.е. знаний js достаточно для написания плагина. Если вам потребуется ts, вы можете поработать над сборщиком и составом пакетов. Но в любом случае исходники CKEditor 5 написаны на ts, и читать код вам будет удобнее, имея соответствующие знания.
А подглядывать в исходники придется, т.к. документация хоть и обширна, но не полна. Там бывают полезные комментарии и примеры кода.
Документация по CKE5 API:
https://ckeditor.com/docs/ckeditor5/latest/api/index.html
Структура плагина CKE5.
Можно выделить три элемента, которые будут присутствовать почти в любом плагине:
- UI,
- Редактирование,
- Реализация CKE комманд.
index.js файл ссылается на два первых элемента, а те используют третий. Нужно определить два метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class BButton extends Plugin { /** * @inheritdoc */ static get requires() { return [BButtonEditing, BButtonUI]; } /** * @inheritdoc */ static get pluginName() { return 'bButton'; } } |
bbuttonui.js файл — реализация интерфейса компонента. Здесь объявляется кнопка в тулбаре и форма, на которой пользователь выбирает параметры компонента, обрабатывается поведение формы и прочие вещи.
Тут же реализуется передача данных из модели редактора в форму и наоборот.
Сама же форма создаётся на базе View компонентов, которые предоставляются ckeditor5/src/ui
ui/formview.js файл — реализация формы. Также я создал несколько простых компонентов на базе View, которых мне не хватало — это Select, для рендеринга <select> и Tag (служит для вывода произвольного html тега).
bbuttonediting.js файл — тут описывается схема компонента и т.н. конверсии, т.е. преобразования модели (model) в представления (view) и наоборот. Представление в редакторе и в html документе могут отличаться. API предоставляет возможность создать конверторы для каждого из случаев, но можно создать и общий конвертор, как это сделано у меня в плагине изначально.
Возможно, позже я воспользуюсь возможностью, чтобы в редакторе кнопка имела иной html код, чем в исходнике документа.
bbuttoncommand.js файл — это низкий уровень преобразования, когда от вас по имеющейся модели требуется задать структуру компонента (согласно заданной схеме). При этом, я так понимаю, контроля над тем, следуете вы схеме или нет в API не заложено.