---
title: "События плагинов и порядок их срабатывания при работе с пользовательскими полями Joomla и использовании FieldsHelper  - WebTolk"
description: "Подробное руководство по событиям Joomla com_fields: жизненный цикл полей в формах и на фронтенде, роль context/item/subject,    триггеры onCustomFields*, доступные данные и точки модификации. С примерами кода, схемами процессов и практическими рецептами."
url: "https://web-tolk.ru/blog/sobytiya-plaginov-i-poryadok-ikh-srabatyvaniya-pri-rabote-s-polzovatelskimi-polyami-joomla-i-ispolzovanii-fieldshelper"
date: "2026-02-16T06:02:51+00:00"
language: "ru-RU"
---

# События плагинов и порядок их срабатывания при работе с пользовательскими полями Joomla и использовании FieldsHelper

 Автор: Сергей Толкачев Создано: 16 февраля 2026 Обновлено: 19 февраля 2026 Просмотров: 858    ![](https://web-tolk.ru/blog/images/blog/sobytiya-plaginov-i-poryadok-ikh-srabatyvaniya-pri-rabote-s-polzovatelskimi-polyami-joomla-i-ispolzovanii-fieldshelper/header.webp)

В процессе работы с Joomla бывает необходимо работать с пользовательским интерфейсом более тонко, чем обычно. Все формы Joomla состоят из стандартных полей, содержанием, стилем отображения, состоянием (включено/выключено, доступно для редактирования или нет и т.д.) можно управлять с помощью плагинов. Да и для нестандартных проектов хорошей практикой является создание одного системного или нескольких плагинов групп "под проект", в которых хранится весь "нестандарт".

В этой статье описаны все триггеры (события), которые вызываются через Event Dispatcher из `administrator/components/com_fields/src/Helper/FieldsHelper.php`, с привязкой к жизненному циклу (порядку этапов работы запроса), аргументам, изменяемым данным и дальнейшему распространению по Joomla. Это поможет вам работать с Joomla свободнее и не опасаясь при этом потерять изменения при очередном обновлении движка.

Подходы, описанные в статье, полезны в тех случаях, когда вы работаете с данными в **com_fields** - механизме создания и редактирования пользовательских полей ядра Joomla и при использовании **FieldsHelper**. Многие сторонние компоненты не используют эту возможность, поэтому данная статья будет полезна лишь частично.

Скрытый текст

Впервые решил попробовать напрячь ИИ и заставить его пособирать инфу по ядру Joomla и, надо сказать, впервые из этого вышло что-то более-менее удобоваримое, пригодное для дальнейшей обработки. Хотя стиль получился не совсем мой и читатель, думаю, легко это заметит - статья получилась шибко "структурированная", - но информация в ней полезная, поэтому оставим её в таком виде. После детальной проверки собранной информации можно сказать, что ИИ сэкономил времени час-полтора. Наверное, это неплохо.

## Базовые понятия: `context`, `item`, `subject`

Перед разбором событий важно различать три важных понятия:

 `context` (контекст)- Это строка формата `компонент.секция`, например `com_content.article`.
- По этой строке Joomla понимает, для какого типа сущности загружать и рендерить кастомные поля.
- Итого: `context` отвечает на вопрос «для чего именно сейчас работаем с полями?».`item` (текущий объект данных)- Это объект конкретной записи, с которой вы работаете (статья, категория, контакт и т.д.).
- Обычно в `item` есть как минимум `id`, часто `catid`, `language` и другие поля компонента.
- Итого: `item` отвечает на вопрос «для какого конкретного объекта сейчас грузим/рендерим значения?».`subject` (основной объект события)- В событиях `onCustomFieldsBeforePrepareField`, `onCustomFieldsPrepareField` и `onCustomFieldsAfterPrepareField` это объект поля (одно кастомное поле).
- В `PrepareDomEvent` это тоже объект поля, для которого строится XML-нода формы.
- Итого: `subject` отвечает на вопрос «что именно мы сейчас меняем внутри обработчика события?».

### Примеры `context` для разных компонентов Joomla

#### Контекст компонента материалов Joomla (com_content)

- `com_content.article` — поля статьи.
- `com_content.categories` — поля категории материалов.

#### Контекст компонента категорий Joomla (com_categories)

При редактировании категории через `com_categories` плагин fields приводит контекст к виду `<extension>.categories` (например, `com_content.categories`), чтобы выбрать правильные поля для целевого компонента. См.: `plugins/system/fields/src/Extension/Fields.php:289` (onContentPrepareForm())

#### Контекст компонента Контакты (com_contact)

- `com_contact.contact` — поля контакта.
- `com_contact.mail` — поля, которые могут использоваться в контексте отправки письма контакту.

### Пример для новичков

Если событие пришло с `context = com_content.article`, `item->id = 35` и `subject->name = author_badge`, то это значит:

1. Работаем с полями статьи (`com_content.article`).
2. Конкретная статья имеет ID `35`.
3. Сейчас в обработчике мы работаем с одним поле, у которого системное имя `author_badge`.

## Где это в жизненном цикле полей Joomla?

Следует различать 2 процесса, у которых есть общие этапы (например, определение `context`, загрузка полей и обработка через плагины), но разные цели: цикл редактирования формы (нужно собрать и показать поля в админке) и цикл отображения значений (нужно подготовить и вывести значения полей в контенте снаружи сайта).

### Цикл 1: Редактирование формы

1. Модель компонента запускает `preprocessForm(...)`.
2. Базовый вызов события `onContentPrepareForm` происходит в `FormBehaviorTrait::preprocessForm()`, когда модель вызывает `parent::preprocessForm($form, $data, $group)`, файл `libraries/src/MVC/Model/FormBehaviorTrait.php:184`.
3. Примеры моделей: 1. `administrator/components/com_content/src/Model/ArticleModel.php:1007` (модель материала в админке Joomla) 2. `administrator/components/com_categories/src/Model/CategoryModel.php:394` (модель категории в стандартном компоненте категорий) 3. `components/com_contact/src/Model/FormModel.php:210` (модель формы обратной связи компонента контактов снаружи сайта) 4. В отдельных моделях возможен ручной вызов события через `dispatch(...)` и объект события. 5. `components/com_contact/src/Model/ContactModel.php:384` (модель одного контакта во фронтенде, метод `getForm()`)
4. Системный плагин `fields` (`plugins/system/fields/src/Extension/Fields.php`) отрабатывает событие `onContentPrepareForm` и вызывает `FieldsHelper::prepareForm(...)`. До вызова `FieldsHelper` плагин нормализует `context` (включая `com_categories.category...` -> `<extension>.categories`) и приводит `$data` к объекту.
5. `FieldsHelper::prepareForm(...)` (`\Joomla\Component\Fields\Administrator\Helper\FieldsHelper`) строит поля формы.
6. Далее `FieldsHelper` загружает список полей, строит XML группы `com_fields`, вызывает событие `onCustomFieldsPrepareDom`, загружает XML в `Form` (бывший `JForm`) и проставляет значения.
7. Если метод `FieldsHelper::extract(...)` ничего не вернул или в контексте нет полей, форма не модифицируется.
8. После сохранения/удаления системный плагин `fields` сохраняет или очищает значения полей.
9. **Сохранение:** вычисляет итоговое значение по каждому полю и пишет в `#__fields_values` через `FieldModel::setFieldValue(...)`.
10. **Удаление:** очищает значения через `cleanupValues(...)`.
11. **Для пользователей com_users** (события `onUserAfterSave`/`onUserAfterDelete`) используется та же логика через проксирование данных в content-события. Например, внутри события `onUserAfterSave` вызывается событие `onContentAfterSave` с контекстом пользователя.

### Цикл 2: Отображение значений

1. Системный плагин `fields` подключается к событиям отображения контента. Основные точки: `onContentPrepare`, `onContentAfterTitle`, `onContentBeforeDisplay`, `onContentAfterDisplay`.
2. На этих шагах вызывается `FieldsHelper::getFields(...)`.
3. В `onContentPrepare` поля подготавливаются с `prepareValue=true` и складываются в `$item->jcfields` (для ручного использования в шаблонах/оверрайдах).
4. В display-ветке (события `onContentAfterTitle`, `onContentBeforeDisplay`, `onContentAfterDisplay`) значения фильтруются по display-позиции и рендерятся через layout `fields.render`. И тогда в вашем материале или контакте вы получаете отрендеренные поля в позициях "до вывода контента", "после вывода контента", "после заголовка".
5. Условия и ветвления отображения. 1. Если `context` не поддерживается (`FieldsHelper::extract(...)`), обработка пропускается. 2. Для `com_tags.tag` используется ветка с перекладкой контекста на `type_alias`.

## Блок-схемы процессов

Ниже 2 блок-схемы для двух процессов из статьи.

### Отображение поля для редактирования (форма создания/редактирования в Joomla)

 Смотреть блок-схему

![](https://web-tolk.ru/blog/images/blog/sobytiya-plaginov-i-poryadok-ikh-srabatyvaniya-pri-rabote-s-polzovatelskimi-polyami-joomla-i-ispolzovanii-fieldshelper/flow_fields_form_editing.webp)

### Отображение значения поля на пользовательской части сайта Joomla

 Смотреть блок-схему

![](https://web-tolk.ru/blog/images/blog/sobytiya-plaginov-i-poryadok-ikh-srabatyvaniya-pri-rabote-s-polzovatelskimi-polyami-joomla-i-ispolzovanii-fieldshelper/flow_fields_frontend_rendering.webp)

## События из `FieldsHelper`

### 1) `onCustomFieldsBeforePrepareField` (перед рендером пользовательского поля)

Событие вызывается **перед основным рендером каждого конкретного поля** в методе `FieldsHelper::getFields()`. Условие вызова: только в ветке подготовки значения, когда в `getFields()` есть `$item->id` и установлен флаг `$prepareValue==true`.

Аргументом события `onCustomFieldsBeforePrepareField` является экземпляр класса объекта события `$event` - `BeforePrepareFieldEvent`, наследующийся от `AbstractPrepareFieldEvent`: - `libraries/src/Event/CustomFields/BeforePrepareFieldEvent.php:21` (класс BeforePrepareFieldEvent) - `libraries/src/Event/CustomFields/AbstractPrepareFieldEvent.php:31` (класс AbstractPrepareFieldEvent)

Из `$event` можно получить:

1. `$event->getContext(): string` - контекст
2. `$event->getItem(): object` - материал, контакт, категорию и т.д. Уточняем ЧТО это за зверь по контексту.
3. `$event->getField(): object` - это `subject`, само поле.

Что можно менять:

1. Свойства поля (`$field->value`, `$field->rawvalue`, доп. свойства вроде `$field->apivalue`).
2. Объект `item` и `context` менять напрямую как аргументы нельзя (immutable event, то есть событие с «непереназначаемыми» аргументами), но можно менять сам объект `item`, если нужно.

Куда изменения идут дальше: тот же объект поля передается в `onCustomFieldsPrepareField`, затем участвует в финальном значении `field->value`, дальше попадает в `jcfields` или layout поля.

### 2) `onCustomFieldsPrepareField` (момент рендера поля)

Момент вызова: сразу после `Before...` в `FieldsHelper::getFields()`. Условие вызова: только в той же prepare-ветке (`$item->id` + активный `$prepareValue`/совпадение display-режима поля). На этом событии плагины пользовательских полей подключают лейауты плагина пользовательского поля из папки `tmpl`.

Event class (класс объекта события): - `libraries/src/Event/CustomFields/PrepareFieldEvent.php:25` (class PrepareFieldEvent)

Event-методы:

1. `$event->getContext(): string` - получаем контекст выполнения
2. `$event->getItem(): object` - получаем материал, категорию и иже с ними
3. `$event->getField(): object` - получаем само поле
4. `$event->addResult(mixed $result): static` - сохраняем результат работы (через `ResultAware`, то есть через встроенный механизм накопления результата)
5. `$event->getArgument('result', [])`- метод для получения аргументов класса события. Обычно используется после вызова события в helper/dispatcher-коде.

Что можно менять:

1. Добавлять результат рендера через `$event->addResult(...)` в адаптере базового плагина `\Joomla\Component\Fields\Administrator\Plugin\FieldsPlugin`, файл `administrator/components/com_fields/src/Plugin/FieldsPlugin.php`, от которого наследуются все плагины пользовательских полей.
2. Модифицировать `subject` (поле) по месту.

Куда изменения идут дальше: `FieldsHelper` берет `result`, фильтрует пустые значения, склеивает массив в строку и передает в `onCustomFieldsAfterPrepareField`.

### 3) `onCustomFieldsAfterPrepareField` (после получения рендера поля)

Момент вызова: после того как получен рендер-результат поля. Условие вызова: только в той же prepare-ветке `getFields()`; если prepare не выполняется, событие не вызывается.

Event class (класс объекта события): класс `AfterPrepareFieldEvent` (файл `libraries/src/Event/CustomFields/AfterPrepareFieldEvent.php`).

Event API (методы):

1. `$event->getContext(): string` - контекст вида `com_content.article` и т.д.
2. `$event->getItem(): object` - сущность, для которой сделали поле.
3. `$event->getField(): object` - само поле
4. `$event->getValue(): mixed` - а вот тут уже можно получить финальное начение поля на текущий момент.
5. `$event->updateValue(mixed $value): static`

На этом этапе можно менять финальный вывод через `$event->updateValue(...)`.

Дальше результат изменений попадает в `$field->value` (смотрим снова `FieldsHelper::getFields()`).

Примечание по совместимости: передача `value` по ссылке сохранена для обратной совместимости со старым кодом, но помечена как устаревшая (`deprecated`).

### 4) `onCustomFieldsPrepareDom`

На этом этапе можно изменять поля XML-формы. Например, в зависимости от условий устанавливать полям атрибуты `readonly` и `disabled`, добавлять / удалять css-классы, описания, согласно синтаксису XML-манифестов Joomla, но программным способом.

```
public function onCustomFieldsPrepareDom($field, \DOMElement $parent, Form $form)
    {
        $fieldNode = parent::onCustomFieldsPrepareDom($field, $parent, $form);

        if (!$fieldNode) {
            return $fieldNode;
        }

        $fieldNode->setAttribute('disabled', 'true');
        $fieldNode->setAttribute('readonly', 'true');
        $fieldNode->setAttribute('class', 'text-danger fw-bold');

        // Возвращаем изменённое поле
        return $fieldNode;
    }
```

Момент вызова №1: при сборке XML формы в `prepareForm()`.

Момент вызова №2: в `FieldModel::checkDefaultValue()` при проверке default value через правило валидации.

Event class для события - `Joomla\CMS\Event\CustomFields\PrepareDomEvent`:

Event API (методы):

1. `$event->getField(): object` - (поле, основной объект события)
2. `$event->getFieldset(): \DOMElement` - филдсет поля
3. `$event->getForm(): \Joomla\CMS\Form\Form` - форма целиком (`Joomla\CMS\Form\Form`)

Что можно менять:

1. DOM-структуру поля (атрибуты, child-узлы, `<option>`, `validate` и т.д.).
2. Объект `form` (например, `setFieldAttribute`, `setValue`).

Куда изменения идут дальше:

1. XML загружается в `Form`. - `administrator/components/com_fields/src/Helper/FieldsHelper.php:486` (prepareForm())
2. Затем значения поля проставляются в form group `com_fields`. - `administrator/components/com_fields/src/Helper/FieldsHelper.php:511` (prepareForm())

### 5) `onCustomFieldsGetTypes`

Момент вызова: при сборке списка типов полей (`getFieldTypes()`). Этот список мы видим при создании нового поля в панели администратора. Один плагин может реализовывать несколько типов полей. Для этого плагин должен иметь несколько лейаутов в папке `tmpl` и соответствующих им xml-файлов параметров в папке `params`. Например, `tmpl/fieldtype1.php` и `params/fieldtype1.xml`. Событие берёт типы полей именно по наличию php-файлов лейаутов.

Event class - `\Joomla\CMS\Event\CustomFields\GetTypesEvent` (файл `libraries/src/Event/CustomFields/GetTypesEvent.php`)

Event API (методы):

1. `$event->addResult(array $typeDefinitionList): static` (через `ResultAware`, основной способ для обработчика)
2. `$event->getArgument('result', [])` (обычно используется после вызова события в helper/dispatcher-коде)

Аргументы:

1. Событие без обязательного `subject` payload (payload = набор данных, переданных в событие).
2. Канал `result` (массив описаний типов).

Что можно менять:

1. Добавлять описания типов через `$event->addResult(...)`: - `type` - `label` - `path` (где form fields) - `rules` (где form rules)
2. Базовый (родительский класс, от которого наследуются плагины полей) `FieldsPlugin` делает это автоматически.

Куда изменения идут дальше: `FieldsHelper` нормализует `path` и `rules`, затем использует их в `prepareForm()` для `FormHelper::addFieldPath/addRulePath`.

## Ограничения мутабельности (возможности менять данные) и immutable events

CustomFields events наследуются от immutable-базы: `libraries/src/Event/AbstractImmutableEvent.php:22`. Это означает, что нельзя переназначать аргументы события (например, `$event['context'] = ...`). Но, можно сделать следующее:

- Можно менять состояние объектов, переданных в аргументах (`subject`, `form`, `fieldset`) — то есть менять их свойства/атрибуты.
- Можно работать через `ResultAware` - есть метод `addResult()`, который позволяет добавлять результат обработчика в общий итог.
- Для `AfterPrepareFieldEvent` можно менять значение через `updateValue` (обновить итоговый вывод поля).

## Как данные прокидываются дальше по Приложению Joomla

### Поток `getFields(...)`

1. Загружает значения из `#__fields_values` (`rawvalue`/`value`), учитывает `valuesToOverride` и `default_value`. 1. `administrator/components/com_fields/src/Helper/FieldsHelper.php:184` (getFields()) 2. `administrator/components/com_fields/src/Helper/FieldsHelper.php:195` (getFields()) 3. `administrator/components/com_fields/src/Helper/FieldsHelper.php:204` (getFields()) 4. `administrator/components/com_fields/src/Helper/FieldsHelper.php:207` (getFields())
2. Прогоняет цепочку `Before -> Prepare -> After` (если активна prepare-ветка, то есть этап подготовки отображаемого значения).
3. Возвращает массив полей; далее он используется: 1. для `$item->jcfields` в `onContentPrepare` 2. для layout рендера HTML-вёрстки поля в `onContentAfterTitle`/`onContentBeforeDisplay`/`onContentAfterDisplay`

### Поток `prepareForm(...)`

1. Строит XML `<fields name="com_fields">`.
2. На каждый field вызывает `onCustomFieldsPrepareDom`, где можно работать с XML-формой через `\DOMElement` (fieldset) и объект Joomla `Form`.
3. Загружает XML в форму и выставляет значения.

## Практические примеры из `com_fields` и core plugins

1. Пример `BeforePrepareField`: нормализация значения перед рендером (`media`, `list`, `radio`, `subform`). 1. `plugins/fields/media/src/Extension/Media.php` (beforePrepareField()) 2. `plugins/fields/list/src/Extension/ListPlugin.php` (beforePrepareField()) 3. `plugins/fields/radio/src/Extension/Radio.php` (beforePrepareField()) 4. `plugins/fields/subform/src/Extension/Subform.php` (beforePrepareField())
2. Пример `PrepareField`: базовый HTML-рендер через layout. 1. `administrator/components/com_fields/src/Plugin/FieldsPlugin.php:211` (onCustomFieldsPrepareField())
3. Пример `AfterPrepareField`: пост-обработка HTML (email cloak). 1. `plugins/content/emailcloak/src/Extension/EmailCloak.php:108` (onCustomFieldsAfterPrepareField())
4. Пример `PrepareDom`: сборка XML ноды поля, валидации и options. 1. `administrator/components/com_fields/src/Plugin/FieldsPlugin.php:245` (onCustomFieldsPrepareDom()) 2. `administrator/components/com_fields/src/Plugin/FieldsListPlugin.php:38` (onCustomFieldsPrepareDom()) 3. `plugins/fields/subform/src/Extension/Subform.php:265` (onCustomFieldsPrepareDom())

## Рецепты

### Как прокинуть своё кастомное значение в layout поля через плагин

Допустим, что нам нужно передать собственное дополнительное значение из плагина в layout этого поля (файл `plugins/fields/<your_plugin>/tmpl/<type>.php`). Мы можем на событии `onCustomFieldsBeforePrepareField` добавить своё свойство в объект поля (`$field`). А в `onCustomFieldsPrepareField` (обычно базовый `FieldsPlugin`) этот же `$field` уже доступен в layout, поэтому наше уникальное свойство можно читать напрямую.

Пример плагина:

```
<?php
use Joomla\CMS\Event\CustomFields\BeforePrepareFieldEvent;
use Joomla\Component\Fields\Administrator\Plugin\FieldsPlugin;
use Joomla\Event\SubscriberInterface;

final class MyCustomSystemPlugin extends FieldsPlugin implements SubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            'onCustomFieldsBeforePrepareField' => 'beforePrepareField',
        ];
    }

    public function beforePrepareField(BeforePrepareFieldEvent $event): void
    {
        $field = $event->getField();

        /**
         * Этот метод срабатывает абсолютно для КАЖДОГО поля. Поэтому срабатываем только в нужном нам типе.
         * В данном случае это поле Яндекс.Карты wtyandexmap
         */
        if ($field->type !== 'wtyandexmap') {
            return;
        }

         /**
          * Тут любая логика. А мы к примеру, добавим,
          * свою картинку в класс поля,
          * чтобы вытащить её напрямую в макете поля.
          * Наименования кастомных свойств лучше брендировать своим префиксом
          * или префиксом проекта, дабы не было случайных пересечений
          * с другими расширениями.
          */
        $field->wt_custom_layout_data = [
            'icon' => 'images/path/to/image.webp'
        ];
    }
}
```

Пример layout-файла поля (`plugins/fields/mycustomsystem/tmpl/mycustomsystem.php`):

```
<?php
/** @var \stdClass $field */

echo '<div class="cf-mytype">';
echo '<span class="cf-value">' . htmlspecialchars((string) $field->value, ENT_QUOTES, 'UTF-8') . '</span>';

// Теперь тут доступно наше кастомное свойство.
if (!empty($field->wt_custom_layout_data['icon'])) {
    echo HTMLHelper::image($field->wt_custom_layout_data['icon'], 'icon-alt', ['class' => 'img-fluid', 'title'=>'icon title']);
}

echo '</div>';
```

Где это в ядре Joomla подтверждается:

1. `FieldsHelper` передаёт поле как `subject` в `BeforePrepareFieldEvent`. - `administrator/components/com_fields/src/Helper/FieldsHelper.php` (метод `getFields()`)
2. Затем то же поле передаётся в `PrepareFieldEvent`. - `administrator/components/com_fields/src/Helper/FieldsHelper.php` (тот же метод `getFields()`)
3. Базовый `FieldsPlugin` внутри `onCustomFieldsPrepareField()` включает макет вывода, где переменная `$field` доступна напрямую. - `administrator/components/com_fields/src/Plugin/FieldsPlugin.php:211` (метод `onCustomFieldsPrepareField()`)

## Примеры кода

### Изменение или замена HTML-вывода значения (value) в момент рендера поля

Пример реализации `onCustomFieldsPrepareField` для изменения итогового HTML значения поля (то, что увидит пользователь на странице). В результате мы контролируем конечную разметку, которую `FieldsHelper` положит в `$field->value`.

```
<?php
public function onCustomFieldsPrepareField($context, $item, $field)
{
    if ($field->type !== 'mytype') {
        return '';
    }
    // Тут мы полностью заменяем HTML-вёрстку из $field->getInput() класса поля на своё
    // или делаем return parent::onCustomFieldsPrepareField($context, $item, $field);
    return '<span class="text-danger">По каким-то причинам мы не хотим показывать value этого поля. Увы... а могли бы сделать <code>return htmlspecialchars((string) $field->value, ENT_QUOTES, "UTF-8");</code>.</span>';
}
```

Но с этим событием нужно быть аккуратнее, так как здесь результат будет зависеть от порядка срабатывания плагинов и от их приоритета. Лучше архитектурно планировать изменения полей в другом месте жизненного цикла, если это необходимо.

### Изменение или замена HTML-вывода значения (value) в ПОСЛЕ рендера поля

Комментарий к примеру: пример пост-обработки уже готового значения поля на `onCustomFieldsAfterPrepareField`. Результат: можно обернуть, заменить или дополнительно фильтровать HTML перед выводом.

```
<?php
use Joomla\CMS\Event\CustomFields\AfterPrepareFieldEvent;

public function onCustomFieldsAfterPrepareField(AfterPrepareFieldEvent $event): void
{
    if (empty($event->getValue())) {
        return;
    }

    $event->updateValue('<div class="wrapped-field">' . $event->getValue() . '</div>');
}
```

### Работа с XML-формой поля Joomla. Добавление / изменение атрибутов поля и т.д.

Комментарий к примеру: пример построения DOM-ноды формы (XML-элемента `<field>`) на `onCustomFieldsPrepareDom`. Результат: поле появляется в `Form` с нужным атрибутом `validate=color` и участвует в стандартной обработке формы.

```
<?php
// Пример из плагина пользовательского поля Color
// файл plugins/fields/color/src/Extension/Color.php
use Joomla\CMS\Form\Form;

public function onCustomFieldsPrepareDom($field, \DOMElement $parent, Form $form)
{
  $fieldNode = parent::onCustomFieldsPrepareDom($field, $parent, $form);

  if (!$fieldNode) {
      return $fieldNode;
  }

  $fieldNode->setAttribute('validate', 'color');

  return $fieldNode;
}
```

Этот механизм может быть полезен тогда, когда вы работаете со стандартными полями Joomla в своём расширении и вам необходимо модифицировать состояние полей в зависимости от данных. Например, не показывать поле и исключить его из обработки в зависимости от наличия данных в других полях: не указал пользователь API-ключ для интеграции со сторонним сервисом - не показываем ему остальную форму вообще (можно вернуть `null` и не добавлять узел поля в поля в DOM-дерево, но тут нужно учитывать логику обработки данных в моделях - как они к этому отнесутся). Или не даём редактировать эти поля с помощью `readonly` и `disabled`. **Но нужно учитывать, что это событие ограничивает применимость логики к сущности одного конкретного поля и описывает его поведение**. Если нужно работать большими блоками в масштабах всей формы, то разумнее использовать событие `onContentPrepareForm` и манипулировать формой на том этапе. Также нужно не забывать о том, что если поле не пришло в `data['com_fields']`, при сохранении в поле может остаться прежнее `rawvalue`.

- [Этот текст на Хабре](https://habr.com/ru/articles/1000064/)
- [Пост в Telegram @webtolkru](https://t.me/webtolkru/905)
- [Эта статья на Joomlaportal.ru](https://joomlaportal.ru/blogs/development/sobytiya-plaginov-i-poryadok-ikh-srabatyvaniya-pri-rabote-s-polzovatelskimi-polyami-joomla-i-ispolzovanii-fieldshelper)

## Об авторе

![Толкачев Сергей Юрьевич](https://web-tolk.ru/images/uslugi/sergey-tolkachyov-apr-2023.webp)

### Толкачев Сергей Юрьевич

Joomla-разработчик. [Контрибьютер ядра Joomla](https://github.com/joomla/joomla-cms/pulls?q=is%3Apr+author%3Asergeytolkachyov+). Один из ведущих Telegram-канала русскоязычного Joomla-сообщества [JoomlaFeed](https://t.me/joomlafeed), один из модераторов [чата русскоязычного Joomla-сообщества](https://t.me/joomlaru). Мои расширения в официальном маркетплейсе расширений Joomla - [Joomla Extensions Directory](https://extensions.joomla.org/profile/profile/details/528051/). Имею публикации в [официальном журнале международного Joomla-сообщества - Joomla Community Magazine](https://magazine.joomla.org/authors/sergeytolkachyov) и на [официальном сайте русскоязычного Joomla-сообщества](https://joomlaportal.ru/users/sergey-tolkachyov).

Муж. Отец 3 детей.

Россия, Саратов.

## JSON-LD Schema

```json
{
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "@id": "https://web-tolk.ru/#/schema/BreadcrumbList/17",
    "itemListElement": [
        {
            "@type": "ListItem",
            "position": 1,
            "item": {
                "@id": "https://web-tolk.ru/",
                "name": "Главная"
            }
        },
        {
            "@type": "ListItem",
            "position": 2,
            "item": {
                "@id": "https://web-tolk.ru/blog",
                "name": "Блог"
            }
        },
        {
            "@type": "ListItem",
            "position": 3,
            "item": {
                "name": "События плагинов и порядок их срабатывания при работе с пользовательскими полями Joomla и использовании FieldsHelper "
            }
        }
    ]
}
```

```json
{
    "@context": "https://schema.org",
    "@graph": [
        {
            "@type": "Organization",
            "@id": "https://web-tolk.ru/#/schema/Organization/base",
            "name": "WebTolk",
            "url": "https://web-tolk.ru/",
            "logo": {
                "@type": "ImageObject",
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo",
                "url": "images/webtolk-1080p.jpg",
                "contentUrl": "images/webtolk-1080p.jpg",
                "width": 1920,
                "height": 1080
            },
            "image": {
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo"
            },
            "sameAs": [
                "https://github.com/WebTolk",
                "https://github.com/sergeytolkachyov",
                "https://vk.com/web_tolk",
                "https://vk.com/webtolkru",
                "https://tenchat.ru/sergeytolkachyov",
                "https://t.me/sergeytolkachyov",
                "https://t.me/webtolkru"
            ]
        },
        {
            "@type": "WebSite",
            "@id": "https://web-tolk.ru/#/schema/WebSite/base",
            "url": "https://web-tolk.ru/",
            "name": "WebTolk",
            "publisher": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            }
        },
        {
            "@type": "WebPage",
            "@id": "https://web-tolk.ru/#/schema/WebPage/base",
            "url": "https://web-tolk.ru/blog/sobytiya-plaginov-i-poryadok-ikh-srabatyvaniya-pri-rabote-s-polzovatelskimi-polyami-joomla-i-ispolzovanii-fieldshelper",
            "name": "События плагинов и порядок их срабатывания при работе с пользовательскими полями Joomla и использовании FieldsHelper  - WebTolk",
            "description": "Подробное руководство по событиям Joomla com_fields: жизненный цикл полей в формах и на фронтенде, роль context/item/subject,\r\n  триггеры onCustomFields*, доступные данные и точки модификации. С примерами кода, схемами процессов и практическими рецептами.",
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebSite/base"
            },
            "about": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            },
            "inLanguage": "ru-RU",
            "breadcrumb": {
                "@id": "https://web-tolk.ru/#/schema/BreadcrumbList/17"
            }
        },
        {
            "@type": "Article",
            "image": "https://web-tolk.ru/images/blog/sobytiya-plaginov-i-poryadok-ikh-srabatyvaniya-pri-rabote-s-polzovatelskimi-polyami-joomla-i-ispolzovanii-fieldshelper/header.webp",
            "headline": "События плагинов и порядок их срабатывания при работе с пользовательскими полями Joomla и использовании FieldsHelper ",
            "description": "Подробное руководство по событиям Joomla com_fields: жизненный цикл полей в формах и на фронтенде, роль context/item/subject,   триггеры onCustomFields*, доступные данные и точки модификации. С примерами кода, схемами процессов и практическими рецептами.",
            "datePublished": "2026-02-16T00:00:00+00:00",
            "@id": "https://web-tolk.ru/#/schema/com_content/article/174",
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebPage/base"
            }
        }
    ]
}
```
