カスタムエレメントの作成.
すべてのDXPR Builderエレメントはwindow.dxprBuilder.dxpr_elementsにプッシュされるJavaScriptオブジェクトです。エディターは各オブジェクトをStyle・Animationタブ付きのエレメントクラスに変換します。このページでは出荷エレメントがdxpr_builder/dxpr_elements.jsで定義される方法、モジュールが独自定義をエディターに追加する方法、結果のHTMLを示します。エレメントごとのサーバー側Twigテンプレートはありません。エレメントはブラウザーでレンダーされます。
エディターのエレメント登録方法
この順序で読み込まれ、dxpr_builder_library_info_build()(dxpr_builder.module内)でdxpr_builder/editor.builderライブラリーとして定義される6つのスクリプトです。
dxpr_templates.js:dxpr_builder/templates/からコンパイルされたクライアント側twig.jsテンプレート。dxpr_global.js:共有ヘルパーとCKEditor 5統合。dxpr_events.jsdxpr_param_types.js:入力タイプごとに1オブジェクトをwindow.dxprBuilder.dxpr_param_typesにプッシュ。dxpr_elements.js:window.dxprBuilder.dxpr_elements配列を作り、エレメントごとに1定義をプッシュ。dxpr_builder.js:エディター。このファイルの実行時にcreate_dxpr_elements()を呼び出し、window.dxprBuilder.dxpr_elementsをループして各定義で以下を実行します。- 呼び出すのは
register_animated_element(base, is_container, Class)で、クラスがAnimatedElementを拡張します(Styleタブ、Animationタブ、HTML ID、HTMLクラス、配置パラメーター)。 - 継承パラメーターを定義の
paramsに追加します。 - 全パラメーターを
make_param_type()で変換します。param.typeを登録済みパラメータータイプと照合します。 - 定義のプロパティをクラスのプロトタイプに混ぜ込みます。
- 呼び出すのは
定義はdxpr_elements.jsの実行後、dxpr_builder.jsの実行前に配列にある必要があります。6ファイルはすべてdefer属性で読み込まれるため、scriptタグの文書順序が実行順序です。
エレメント定義
例はdxpr_builder/dxpr_elements.jsのAlertエレメントです(ソース: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と一緒に使い、値を<img>属性に保存するもので、data-azat-*を使わないImageなどのエレメント向けです。 |
パラメーター
各項目は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を所有済みのため、その名の2つ目のパラメーターがdata-azat-colorに書き込まれることはありません。
保存内容
update_data()(dxpr_builder.js内)はエレメントをHTMLに書き込みます。
data-azb="<base>"はルートエレメントに。data-azat-<param_name>="<value>"は初期値と異なる値の全パラメーターに。パラメーターがsafe: trueを設定しない限りURLエンコードされます。- 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>を添付します。キーはdxpr_builder.libraries.ymlのelements.*ライブラリーです。スラッシュ付きキーは登録済みアイコンセットのlibraryである場合のみ有効です。
最小動作例
例では選択色で段落をレンダーする「Notice」エレメントを追加します。dxpr_templates.jsのコンパイル済みtwig.jsテンプレートはエディターバンドルの一部で他モジュールから拡張できないため、DOMを直接構築します。
-
作るのは
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由来でもローカルビルド由来でもファイルの順序位置を保ちます。 -
キャッシュをクリアしてBuilderページを開きます。
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*属性なしで同じマークアップを受け取ります。段落はインライン色を保つため、このエレメントに訪問者用ライブラリーは不要です。
把握すべき制限
- プロフィールはカスタムエレメントを列挙しません。Builderプロフィールのエレメントチェックリストは
src/Form/DxprBuilderProfileForm.phpとsrc/Service/Handler/ProfileHandler.phpの固定リストから来ます。その外のエレメントはプロフィールで隠れません。 - ピッカーのアイコンはモジュールからのCSSが必要です。Builder出荷の
az-custom-iconクラスは出荷エレメントのみを対象とします。 DxprBuilderService::getDxprElementsFolders()とhook_dxpr_builder_elements_folders_alter()はテーマ内のelementsフォルダーの一覧を返しますが、エディターは何も読み取りません。登録ルートではありません。- StyleとAnimationタブは
register_animated_element()が追加します。そのパラメーターを再定義しません。