Створення власних елементів.
Кожен елемент DXPR Builder це об’єкт JavaScript, доданий до
window.dxprBuilder.dxpr_elements. Редактор перетворює кожен об’єкт
на клас елемента з уже приєднаними вкладками Style і Animation. Ця
сторінка показує, як вбудовані елементи визначено в
dxpr_builder/dxpr_elements.js, як модуль додає власне
визначення до редактора, і як виглядає результатний HTML.
Серверних Twig-шаблонів на елемент немає; елементи
рендеряться в браузері.
Як редактор реєструє елементи
Редактор завантажує шість скриптів у такому порядку, визначених у
dxpr_builder_library_info_build() в dxpr_builder.module як
бібліотека dxpr_builder/editor.builder:
dxpr_templates.js: клієнтські шаблони twig.js, скомпільовані зdxpr_builder/templates/.dxpr_global.js: спільні помічники та інтеграція CKEditor 5.dxpr_events.jsdxpr_param_types.js: додає по одному об’єкту на тип вводу доwindow.dxprBuilder.dxpr_param_types.dxpr_elements.js: створює масивwindow.dxprBuilder.dxpr_elementsі додає по одному визначенню на елемент.dxpr_builder.js: редактор. Коли цей файл виконується, він викликаєcreate_dxpr_elements(), який проходить циклом поwindow.dxprBuilder.dxpr_elementsі для кожного визначення:- викликає
register_animated_element(base, is_container, Class), тож клас розширюєAnimatedElement(вкладка Style, вкладка Animation, HTML ID, HTML classes і параметри розміщення); - додає успадковані параметри до
paramsвизначення; - конвертує кожен параметр через
make_param_type(), який зіставляєparam.typeіз зареєстрованими типами параметрів; - змішує властивості визначення в прототип класу.
- викликає
Визначення тому мусить бути на масиві після
виконання dxpr_elements.js і перед виконанням dxpr_builder.js. Усі
шість файлів завантажуються з атрибутом defer, тож порядок тегів
скриптів у документі це порядок виконання.
Визначення елемента
Це елемент Alert із dxpr_builder/dxpr_elements.js
(джерело: dxpr_builder/build/dxpr-elements/elements/az_alert.js),
обрізаний до властивостей, потрібних кожному елементу. Оригінал також
встановлює el_class, обробник onCancel і слухача focusout.
window.dxprBuilder.dxpr_elements.push({
base: "az_alert",
name: Drupal.t("Alert"),
nameEn: "Alert",
icon: "az-custom-icon az-alert-icon",
largeSettingsWindow: true,
hidden: false,
params: [
{
type: "textarea",
heading: Drupal.t("Message"),
param_name: "content",
value: Drupal.t(
"This is a placeholder text. Your actual content will go here. Edit this to include your own information.",
),
},
{
type: "dropdown",
heading: Drupal.t("Type"),
param_name: "type",
description: Drupal.t("Select message type."),
getText: (opt) => opt.text,
getValue: (opt) => opt.value,
getDefault: (param) => param.value["alert-success"].value,
value: {
"alert-success": { text: Drupal.t("Success"), value: "alert-success" },
"alert-info": { text: Drupal.t("Info"), value: "alert-info" },
"alert-warning": { text: Drupal.t("Warning"), value: "alert-warning" },
"alert-danger": { text: Drupal.t("Danger"), value: "alert-danger" },
},
passthrough: true,
},
],
show_settings_on_create: true,
has_content: true,
render(...args) {
const state = {
class: `az-element az-alert alert ${this.attrs.type} ${this.get_el_classes()} ${this.get_content_classes()}`,
style: this.attrs.style,
message: this.attrs.content,
};
this.dom_element = this.baseclass.prototype.render_template(
"elements/alert/alert",
state,
);
this.baseclass.prototype.render.apply(this, args);
},
save_history() {
const container = this.get_my_container();
container.save_container_history(Drupal.t("Edit alert"));
},
});
| Властивість | Призначення |
|---|---|
base |
Машинне ім’я. Воно пишеться у збережений HTML як data-azb="az_alert" і використовується для пошуку класу, коли сторінка розбирається знову. Зберігайте префікс az_. |
name, nameEn |
Мітка у виборі елементів та її неперекладена форма. |
icon |
CSS-класи для піктограми вибору. Вбудовані піктограми визначено в dxpr_builder/sass/dxpr-builder-backend/components/_custom-icons.scss; власний елемент потребує власного CSS для свого класу піктограми. |
category |
Вкладка вибору. Елементи макета використовують Drupal.t("Layout"); блоки та подання використовують "CMS". Опустіть її для типової вкладки вмісту. |
is_container |
true, коли елемент тримає інші елементи. |
largeSettingsWindow |
Відкриває діалогове вікно налаштувань у більшому розмірі. |
hidden |
Ховає елемент із вибору, зберігаючи його рендереним. |
params |
Налаштування, показані в діалоговому вікні. Див. нижче. |
show_settings_on_create |
Відкриває діалогове вікно налаштувань, щойно елемент скинуто. |
has_content |
Елемент має редаговану область вмісту (dom_content_element). |
render(...args) |
Будує this.dom_element з this.attrs, потім викликає базовий render. |
save_history() |
Додає запис скасування з міткою. |
parse_attrs_from_dom(element) |
Необов’язково. Читає значення параметрів назад зі збереженої розмітки, використовується разом із skip_data_azb і skip_params елементами на кшталт Image, які зберігають значення в атрибутах <img> замість data-azat-*. |
Параметри
Кожен запис у params має:
| Ключ | Значення |
|---|---|
type |
Один із зареєстрованих типів параметрів (наступний розділ). |
heading |
Мітка поля. |
param_name |
Ключ у this.attrs і, у збереженому HTML, атрибут data-azat-<param_name>. content особливий: це тіло елемента, а не атрибут. |
value |
Типове значення. Для dropdown це об’єкт параметрів із колбеками getText, getValue і getDefault. |
description |
Текст довідки під полем. |
tab |
Групує поле в іменований акордеон, наприклад Drupal.t("SEO"). |
can_be_empty |
Зберігає порожній рядок замість опускання атрибута. |
safe |
Пропускає URL-кодування збереженого значення. |
Типи параметрів це значення type, додані до
window.dxprBuilder.dxpr_param_types у
dxpr_builder/dxpr_param_types.js: boxmodel, checkbox,
checkboxes, colorpicker, datetime, dropdown, dxb_slider,
html, icon, image, images, link, links, numericfield,
row_layout, saved_datetime, social_links, textarea,
textfield і video. Незареєстрований вами тип відкочується до
звичайного текстового вводу (BaseParamType).
Не використовуйте повторно param_name, який успадковує кожен елемент, як-от
color, background, el_class, hash або імена
анімації an_*. Вкладка Style вже володіє color, тож другий параметр
із цим іменем ніколи не пишеться в data-azat-color.
Що зберігається
update_data() у dxpr_builder.js пише елемент у HTML:
data-azb="<base>"на кореневому елементі;data-azat-<param_name>="<value>"для кожного параметра, чиє значення відрізняється від типового, URL-закодовано, якщо параметр не встановлюєsafe: true;- параметри вкладки Style як вбудовані
styleі класи, ніколи як атрибутиdata-azat-*; data-azcnt="true"на елементі вмісту, коли встановленоhas_content.
Глядачі, які не отримують редактор, отримують цей HTML без його
атрибутів data-az*: DxprBuilderService::parseDocumentForCleanup()
здирає їх, крім фіксованого списку, який він тримає на анімованих елементах і
на вбудованих динамічних елементах на кшталт Carousel. Якщо
елемент потребує JavaScript або CSS для відвідувачів, покладіть
атрибут data-dxpr-builder-libraries="<key>" на його корінь:
parseDocumentForTemplateLibrary() приєднує
dxpr_builder/elements.<key> для кожного ключа без слеша. Ключі
це бібліотеки elements.* у dxpr_builder.libraries.yml;
ключ зі слешом шанується лише коли він є library
зареєстрованого набору піктограм.
Мінімальний робочий приклад
Приклад додає елемент «Notice», який рендерить абзац із
вибраним кольором. Він будує свій DOM напряму, бо скомпільовані шаблони
twig.js у dxpr_templates.js є частиною пакета редактора й
не можуть бути розширені іншим модулем.
-
Створіть
mymodule/js/notice-element.js:window.dxprBuilder.dxpr_elements.push({ base: "az_notice", name: Drupal.t("Notice"), nameEn: "Notice", icon: "az-custom-icon az-alert-icon", params: [ { type: "textfield", heading: Drupal.t("Text"), param_name: "text", value: Drupal.t("Notice text"), }, { type: "colorpicker", heading: Drupal.t("Colour"), param_name: "notice_color", value: "#0d6efd", }, ], show_settings_on_create: true, render(...args) { const el = document.createElement("div"); el.className = `az-element az-notice ${this.get_el_classes()}`; if (this.attrs.style) { el.setAttribute("style", this.attrs.style); } const p = document.createElement("p"); p.style.color = this.attrs.notice_color; p.textContent = this.attrs.text; el.appendChild(p); this.dom_element = el; this.baseclass.prototype.render.apply(this, args); }, save_history() { this.get_my_container().save_container_history(Drupal.t("Edit notice")); }, }); -
Вставте файл у бібліотеку редактора між
dxpr_elements.js(вага-4) іdxpr_builder.js(вага-3) уmymodule.module:/** * Implements hook_library_info_alter(). */ function mymodule_library_info_alter(array &$libraries, string $extension): void { if ($extension === 'dxpr_builder' && isset($libraries['editor.builder'])) { $path = '/' . \Drupal::service('extension.list.module')->getPath('mymodule'); $libraries['editor.builder']['js'][$path . '/js/notice-element.js'] = [ 'weight' => -3.5, 'preprocess' => FALSE, 'attributes' => ['defer' => TRUE], ]; } }preprocess: FALSEіdeferвідповідають записам, які модуль визначає для власних файлів, тож файл зберігає своє місце в послідовності, чи ресурси редактора походять із CDN, чи з локальної збірки. -
Очистьте кеш і відкрийте сторінку конструктора:
drush cr -
Додайте елемент із вибору, встановіть його текст і колір, і збережіть. Поле зберігає:
<div class="az-element az-notice" id="..." data-azb="az_notice" data-azat-text="Hello" data-azat-notice_color="%23198754"> <p style="color: #198754;">Hello</p> </div>Відвідувач отримує ту саму розмітку без атрибутів
data-az*. Абзац зберігає свій вбудований колір, тож бібліотека для відвідувачів для цього елемента не потрібна.
Обмеження, які варто знати
- Профілі не перелічують власних елементів. Контрольний список
елементів у профілі конструктора походить із фіксованого списку в
src/Form/DxprBuilderProfileForm.phpіsrc/Service/Handler/ProfileHandler.php. Елементи поза цим списком ніколи не ховаються профілем. - Піктограми для вибору потребують CSS з вашого модуля;
класи
az-custom-icon, які постачає конструктор, охоплюють лише вбудовані елементи. DxprBuilderService::getDxprElementsFolders()і йогоhook_dxpr_builder_elements_folders_alter()повертають список текelementsу темах, але ніщо в редакторі не читає цей список. Це не маршрут реєстрації.- Вкладки Style і Animation додаються за вас через
register_animated_element(); не перевизначайте ці параметри.
Що далі?
- Hooks API для PHP-хуків, які додають службові класи та набори піктограм.
- Архітектура для того, як редактор і форматувальник поля пасують одне одному.