사용자 정의 요소 만들기.

Learn DXPR BuilderExtendBouw erop voort

모든 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 라이브러리로서:

  1. dxpr_templates.js: dxpr_builder/templates/에서 컴파일된 클라이언트 측 twig.js 템플릿.
  2. dxpr_global.js: 공유 도우미와 CKEditor 5 통합.
  3. dxpr_events.js
  4. dxpr_param_types.js: 입력 유형마다 하나의 객체를 다음에 푸시: window.dxprBuilder.dxpr_param_types.
  5. dxpr_elements.js: window.dxprBuilder.dxpr_elements 배열을 만들고 요소마다 하나의 정의를 푸시.
  6. 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가 실행되기 전에 배열에 있어야 합니다. 여섯 파일은 모두 defer 특성으로 불러오므로 스크립트 태그의 문서 순서가 실행 순서입니다.

요소 정의

다음은 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> 특성에 저장하는 Image 같은 요소용(data-azat-* 대신).

매개변수

각 항목 구성(params)

키 의미
type 등록된 매개변수 유형 중 하나(다음 섹션).
heading 필드 레이블.
param_name 다음의 키이자 저장된 HTML에서는 특성: 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>". 기본값과 다른 모든 매개변수용. 매개변수가 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" 요소를 추가합니다. 컴파일된 twig.js 템플릿(dxpr_templates.js 안)이 편집기 번들의 일부이며 다른 모듈이 확장할 수 없으므로 DOM을 직접 만듭니다.

  1. 다음을 만드세요: 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"));
      },
    });
    
  2. 파일을 편집기 라이브러리의 다음 사이에 삽입하세요: 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에서 오든 로컬 빌드에서 오든 파일이 순서에서 자리를 유지합니다.

  3. 캐시를 지우고 빌더 페이지를 여세요:

    drush cr
    
  4. 선택기에서 요소를 추가하고 텍스트와 색상을 정한 뒤 저장하세요. 필드 저장 내용:

    <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()(이)가 추가해 줍니다. 해당 매개변수를 재정의하지 마세요.

다음 단계

  • 후크 API. 유틸리티 클래스와 아이콘 세트를 추가하는 PHP 후크에 대한 내용.
  • 아키텍처. 편집기와 필드 포매터가 어떻게 맞물리는지에 대한 내용.