---
url: 'https://dxpr.com/ko/hc/documentation/learn-dxpr-builder/development/custom-elements'
title: '사용자 정의 요소 만들기 | DXPR'
author:
  name: Jurriaan
  url: 'https://dxpr.com/users/jurriaan'
date: '2026-10-24T01:40:35+00:00'
updated: '2026-10-24T09:09:48+00:00'
copyright: 'Copyright DXPR. All rights reserved.'
type: article
summary: |-
  모든 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 라이브러리로서:
tags:
  - 'Bouw erop voort'
image: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
published: true
og:
  site_name: DXPR
  updated_time: '2026-10-24T09:09:48+0000'
  'image:alt': 'DXPR, powered by Drupal: AI-powered Drupal for marketers.'
schema:
  '@context': 'https://schema.org'
  '@graph':
    -
      mainEntity: {  }
    -
      '@type': TechArticle
      headline: '사용자 정의 요소 만들기'
      description: |-
        모든 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 라이브러리로서:
      image:
        '@type': ImageObject
        url: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
        width: '1200'
        height: '630'
      datePublished: '2026-10-24T01:40:35+0000'
      dateModified: '2026-10-24T09:09:48+0000'
      author:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      mainEntityOfPage: 'https://dxpr.com/ko/hc/documentation/learn-dxpr-builder/development/custom-elements'
      articleSection: 'Bouw erop voort'
    -
      '@type': WebPage
      '@id': 'https://dxpr.com/ko/hc/documentation/learn-dxpr-builder/development/custom-elements'
      description: |-
        모든 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 라이브러리로서:
      breadcrumb:
        '@type': BreadcrumbList
        itemListElement:
          -
            '@type': ListItem
            position: 1
            name: 홈
            item: 'https://dxpr.com/ko'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
      inLanguage: ko
---
[Help Center](/ko/node/75)/[Documentation](/ko/hc/documentation) /[Learn DXPR Builder](/hc/documentation/learn-dxpr-builder) /[Extend](/hc/documentation/learn-dxpr-builder/extend) /[Bouw erop voort](/hc/documentation/learn-dxpr-builder/extend/build-on-it) # 사용자 정의 요소 만들기.

 Learn DXPR BuilderExtendBouw erop voort

   ## In this guide

 Related guides

- [후크 API 참조](/ko/hc/documentation/learn-dxpr-builder/development/hooks-api)
- [아키텍처](/ko/hc/documentation/learn-dxpr-builder/development/architecture)

모든 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` 리스너도 있습니다.

```javascript
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`.

    ```javascript
    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`.

    ```php
    /**
     * 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. 캐시를 지우고 빌더 페이지를 여세요:

    ```bash
    drush cr

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

    ```html
    <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](/ko/hc/documentation/learn-dxpr-builder/development/hooks-api). 유틸리티 클래스와 아이콘 세트를 추가하는 PHP 후크에 대한 내용.
- [아키텍처](/ko/hc/documentation/learn-dxpr-builder/development/architecture). 편집기와 필드 포매터가 어떻게 맞물리는지에 대한 내용.