Aangepaste elementen maken.
Elk DXPR Builder-element is een JavaScript-object gepusht op
window.dxprBuilder.dxpr_elements. De editor maakt van elk object
een elementklasse met de tabbladen Style en Animation er al
aan. Deze pagina toont hoe de meegeleverde elementen zijn gedefinieerd in
dxpr_builder/dxpr_elements.js, hoe een module zijn eigen
definitie aan de editor toevoegt en hoe de resulterende HTML eruitziet.
Er zijn geen Twig-sjablonen per element aan de serverkant; elementen
renderen in de browser.
Hoe de editor elementen registreert
De editor laadt zes scripts in deze volgorde, gedefinieerd in
dxpr_builder_library_info_build() in dxpr_builder.module als de
dxpr_builder/editor.builder-library:
dxpr_templates.js: twig.js-sjablonen aan de clientkant gecompileerd uitdxpr_builder/templates/.dxpr_global.js: gedeelde helpers en de CKEditor 5-integratie.dxpr_events.jsdxpr_param_types.js: pusht één object per inputtype opwindow.dxprBuilder.dxpr_param_types.dxpr_elements.js: maakt de arraywindow.dxprBuilder.dxpr_elementsen pusht één definitie per element.dxpr_builder.js: de editor. Wanneer dit bestand wordt uitgevoerd roept hetcreate_dxpr_elements()aan, dat overwindow.dxprBuilder.dxpr_elementsloopt en voor elke definitie:- roept
register_animated_element(base, is_container, Class)aan, zodat de klasseAnimatedElementuitbreidt (tabblad Style, tabblad Animation, HTML ID, HTML classes en plaatsingsparameters); - hangt de overgeërfde parameters aan de
paramsvan de definitie; - converteert elke parameter via
make_param_type(), datparam.typematcht met de geregistreerde parametertypen; - mixt de eigenschappen van de definitie in het klasseprototype.
- roept
Een definitie moet dus op de array staan nadat dxpr_elements.js heeft gedraaid en voordat
dxpr_builder.js draait. Alle zes bestanden laden met het attribuut defer, dus de
documentvolgorde van de scripttags is de uitvoeringsvolgorde.
De elementdefinitie
Dit is het Alert-element van dxpr_builder/dxpr_elements.js
(bron: dxpr_builder/build/dxpr-elements/elements/az_alert.js),
ingekort tot de eigenschappen die elk element nodig heeft. Het origineel stelt ook
el_class, een onCancel-handler en een focusout-listener in.
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"));
},
});
| Eigenschap | Doel |
|---|---|
base |
Machinenaam. Hij wordt in de opgeslagen HTML geschreven als data-azb="az_alert" en gebruikt om de klasse te vinden wanneer de pagina opnieuw wordt geparsed. Houd de prefix az_ aan. |
name, nameEn |
Label in de elementkiezer en zijn niet-vertaalde vorm. |
icon |
CSS-klassen voor het kiezerpictogram. De meegeleverde pictogrammen zijn gedefinieerd in dxpr_builder/sass/dxpr-builder-backend/components/_custom-icons.scss; een aangepast element heeft eigen CSS nodig voor zijn pictogramklasse. |
category |
Kiezer-tabblad. De lay-outelementen gebruiken Drupal.t("Layout"); blokken en views gebruiken "CMS". Laat het weg voor het standaard inhoudstabblad. |
is_container |
true wanneer het element andere elementen bevat. |
largeSettingsWindow |
Opent het instellingendialoogvenster in de grotere maat. |
hidden |
Verbergt het element voor de kiezer terwijl het renderbaar blijft. |
params |
Instellingen getoond in het dialoogvenster. Zie hieronder. |
show_settings_on_create |
Opent het instellingendialoogvenster zodra het element wordt neergezet. |
has_content |
Het element heeft een bewerkbaar inhoudsgebied (dom_content_element). |
render(...args) |
Bouwt this.dom_element uit this.attrs, en roept daarna de basis-render aan. |
save_history() |
Pusht een undo-vermelding met een label. |
parse_attrs_from_dom(element) |
Optioneel. Leest parameterwaarden terug uit opgeslagen markup, samen gebruikt met skip_data_azb en skip_params door elementen zoals Image die waarden in de <img>-attributen bewaren in plaats van data-azat-*. |
Parameters
Elke vermelding in params heeft:
| Sleutel | Betekenis |
|---|---|
type |
Een van de geregistreerde parametertypen (volgende sectie). |
heading |
Veldlabel. |
param_name |
Sleutel in this.attrs en, in opgeslagen HTML, het attribuut data-azat-<param_name>. content is speciaal: het is de elementbody, geen attribuut. |
value |
Standaardwaarde. Voor dropdown is het een object met opties met getText-, getValue- en getDefault-callbacks. |
description |
Hulptekst onder het veld. |
tab |
Groepeert het veld in een benoemde accordeon, bijvoorbeeld Drupal.t("SEO"). |
can_be_empty |
Bewaar een lege string in plaats van het attribuut te laten vallen. |
safe |
Sla URL-codering van de opgeslagen waarde over. |
De parametertypen zijn de type-waarden gepusht op
window.dxprBuilder.dxpr_param_types in
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 en video. Een type dat je niet registreert valt terug op een gewone
tekstinput (BaseParamType).
Hergebruik geen param_name die elk element overerft, zoals
color, background, el_class, hash of de an_*-animatienamen.
Het tabblad Style bezit color al, dus een tweede parameter met die naam wordt nooit naar
data-azat-color geschreven.
Wat wordt opgeslagen
update_data() in dxpr_builder.js schrijft het element naar HTML:
data-azb="<base>"op het rootelement;data-azat-<param_name>="<value>"voor elke parameter waarvan de waarde afwijkt van zijn standaard, URL-gecodeerd tenzij de parametersafe: truezet;- de Style-tabbladparameters als inline
styleen klassen, nooit alsdata-azat-*-attributen; data-azcnt="true"op het inhoudselement wanneerhas_contentis ingesteld.
Kijkers die de editor niet krijgen ontvangen deze HTML zonder zijn
data-az*-attributen: DxprBuilderService::parseDocumentForCleanup()
stript ze, behalve een vaste lijst die hij behoudt op geanimeerde elementen en
op ingebouwde dynamische elementen zoals Carousel. Als het
element JavaScript of CSS nodig heeft voor bezoekers, zet je een
data-dxpr-builder-libraries="<key>"-attribuut op zijn root:
parseDocumentForTemplateLibrary() koppelt
dxpr_builder/elements.<key> voor elke key zonder slash. De
keys zijn de elements.*-libraries in dxpr_builder.libraries.yml;
een key met een slash wordt alleen gehonoreerd wanneer het de library is van een
geregistreerde pictogrammenset.
Minimaal werkend voorbeeld
Het voorbeeld voegt een "Notice"-element toe dat een alinea met een
gekozen kleur rendert. Het bouwt zijn DOM direct omdat de gecompileerde twig.js-sjablonen
in dxpr_templates.js deel zijn van de editorbundle en niet door een andere module kunnen worden
uitgebreid.
-
Maak
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")); }, }); -
Voeg het bestand in de editorlibrary in tussen
dxpr_elements.js(gewicht-4) endxpr_builder.js(gewicht-3) inmymodule.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: FALSEendefermatchen de vermeldingen die de module definieert voor zijn eigen bestanden, zodat het bestand zijn plek in de volgorde behoudt of editorassets nu uit het CDN of uit een lokale build komen. -
Wis de cache en open een builderpagina:
drush cr -
Voeg het element uit de kiezer toe, stel zijn tekst en kleur in en sla op. Het veld bewaart:
<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>Een bezoeker krijgt dezelfde markup zonder de
data-az*-attributen. De alinea behoudt zijn inline kleur, dus voor dit element is geen bezoekerslibrary nodig.
Limieten om te kennen
- Profielen vermelden geen aangepaste elementen. De elementchecklist
in een builderprofiel komt uit een vaste lijst in
src/Form/DxprBuilderProfileForm.phpensrc/Service/Handler/ProfileHandler.php. Elementen buiten die lijst worden nooit door een profiel verborgen. - Pictogrammen voor de kiezer hebben CSS nodig van je module; de
az-custom-icon-klassen meegeleverd door de builder dekken alleen de meegeleverde elementen. DxprBuilderService::getDxprElementsFolders()en zijnhook_dxpr_builder_elements_folders_alter()geven een lijst metelements-mappen in thema's terug, maar niets in de editor leest die lijst. Het is geen registratiroute.- Style- en Animation-tabbladen worden voor je toegevoegd door
register_animated_element(); herdefinieer die parameters niet.
Wat nu?
- Hooks API voor de PHP-hooks die utility-klassen en pictogrammensets toevoegen.
- Architectuur voor hoe de editor en de veldformatter in elkaar passen.