---
url: 'https://dxpr.com/ar/hc/documentation/learn-dxpr-builder/development/custom-elements'
title: 'إنشاء عناصر مخصصة | DXPR'
author:
  name: Jurriaan
  url: 'https://dxpr.com/users/jurriaan'
date: '2026-10-24T01:25:32+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. فيحوّل المحرّر كل كائن
  إلى صنف عنصر مع تبويبي النمط والحركة مرفقين أصلًا.
  توضح هذه الصفحة كيفية تعريف العناصر المشحونة في
  dxpr_builder/dxpr_elements.js، وكيف تضيف الوحدة تعريفها الخاص
  إلى المحرّر، وكيف يبدو HTML الناتج.
  لا توجد قوالب Twig من جهة الخادم لكل عنصر؛ فالعناصر تُعرض
  في المتصفح.
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. فيحوّل المحرّر كل كائن
        إلى صنف عنصر مع تبويبي النمط والحركة مرفقين أصلًا.
        توضح هذه الصفحة كيفية تعريف العناصر المشحونة في
        dxpr_builder/dxpr_elements.js، وكيف تضيف الوحدة تعريفها الخاص
        إلى المحرّر، وكيف يبدو HTML الناتج.
        لا توجد قوالب Twig من جهة الخادم لكل عنصر؛ فالعناصر تُعرض
        في المتصفح.
      image:
        '@type': ImageObject
        url: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
        width: '1200'
        height: '630'
      datePublished: '2026-10-24T01:25:32+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/ar/hc/documentation/learn-dxpr-builder/development/custom-elements'
      articleSection: 'Bouw erop voort'
    -
      '@type': WebPage
      '@id': 'https://dxpr.com/ar/hc/documentation/learn-dxpr-builder/development/custom-elements'
      description: |-
        كل عنصر في DXPR Builder كائن JavaScript مدفوع إلى
        window.dxprBuilder.dxpr_elements. فيحوّل المحرّر كل كائن
        إلى صنف عنصر مع تبويبي النمط والحركة مرفقين أصلًا.
        توضح هذه الصفحة كيفية تعريف العناصر المشحونة في
        dxpr_builder/dxpr_elements.js، وكيف تضيف الوحدة تعريفها الخاص
        إلى المحرّر، وكيف يبدو HTML الناتج.
        لا توجد قوالب Twig من جهة الخادم لكل عنصر؛ فالعناصر تُعرض
        في المتصفح.
      breadcrumb:
        '@type': BreadcrumbList
        itemListElement:
          -
            '@type': ListItem
            position: 1
            name: الرئيسية
            item: 'https://dxpr.com/ar'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
      inLanguage: ar
---
[Help Center](/ar/hc)/[Documentation](/ar/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

- [مرجع واجهة الخطافات](/ar/hc/documentation/learn-dxpr-builder/development/hooks-api)
- [البنية](/ar/hc/documentation/learn-dxpr-builder/development/architecture)

كل عنصر في DXPR Builder كائن JavaScript مدفوع إلى `window.dxprBuilder.dxpr_elements`. فيحوّل المحرّر كل كائن إلى صنف عنصر مع تبويبي النمط والحركة مرفقين أصلًا. توضح هذه الصفحة كيفية تعريف العناصر المشحونة في `dxpr_builder/dxpr_elements.js`، وكيف تضيف الوحدة تعريفها الخاص إلى المحرّر، وكيف يبدو HTML الناتج. لا توجد قوالب Twig من جهة الخادم لكل عنصر؛ فالعناصر تُعرض في المتصفح.

## كيف يسجّل المحرّر العناصر

يحمّل المحرّر ستة نصوص بهذا الترتيب، معرّفة في `dxpr_builder_library_info_build()` في `dxpr_builder.module` كمكتبة `dxpr_builder/editor.builder`:

1. `dxpr_templates.js`: قوالب twig.js من جهة العميل مُجمَّعة من `dxpr_builder/templates/`.
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` (تبويب النمط وتبويب الحركة ومعرّف HTML وفئات HTML ومعاملات الموضع)؛
    - تُلحق المعاملات الموروثة بـ `params` الخاصة بالتعريف؛
    - تحوّل كل معامل عبر `make_param_type()` التي تطابق `param.type` مع أنواع المعاملات المسجلة؛
    - تمزج خصائص التعريف في نموذج الصنف الأولي.

يجب لذلك أن يكون التعريف على المصفوفة بعد عمل `dxpr_elements.js` وقبل عمل `dxpr_builder.js`. وتُحمَّل الملفات الستة كلها مع السمة `defer`، فترتيب وسوم النصوص في المستند هو ترتيب التنفيذ.

## تعريف العنصر

هذا عنصر التنبيه من `dxpr_builder/dxpr_elements.js`(المصدر: `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>` بدل `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_*` الخاصة بالحركة. فتبويب النمط يملك `color` أصلًا، فلا يُكتَب معامل ثانٍ بهذا الاسم أبدًا في `data-azat-color`.

### ما يُحفَظ

`update_data()` في `dxpr_builder.js` تكتب العنصر إلى HTML:

- `data-azb="<base>"` على العنصر الجذري؛
- `data-azat-<param_name>="<value>"` لكل معامل تختلف قيمته عن الافتراضي، مرمّزة بترميز URL ما لم يضبط المعامل `safe: true`؛
- معاملات تبويب النمط كـ `style` مضمّنة وفئات، أبدًا كسمات `data-azat-*`؛
- `data-azcnt="true"` على عنصر المحتوى عندما يُضبَط `has_content`.

يستقبل المشاهِدون الذين لا يحصلون على المحرّر HTML هذا دون سماته `data-az*`: فيجرّدها `DxprBuilderService::parseDocumentForCleanup()`، عدا قائمة ثابتة يُبقيها على العناصر المتحركة وعلى العناصر الديناميكية المدمجة مثل الدوّار. وإذا احتاج العنصر 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` جزء من حزمة المحرّر ولا تستطيع وحدة أخرى توسيعها.

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` في القوالب، لكن لا شيء في المحرّر يقرأ تلك القائمة. فليست مسار تسجيل.
- **تبويبا النمط والحركة** يُضافان لكم عبر `register_animated_element()`؛ فلا تعيدوا تعريف تلك المعاملات.

## ما الخطوة التالية؟

- [واجهة الخطافات](/ar/hc/documentation/learn-dxpr-builder/development/hooks-api) لخطافات PHP التي تضيف فئات الأدوات ومجموعات الأيقونات.
- [البنية](/ar/hc/documentation/learn-dxpr-builder/development/architecture) لكيفية تلاؤم المحرّر ومُنسِّق الحقل معًا.