Плагины Joomla: типы, события и выбор точки расширения
В Joomla плагин подключается не к странице, а к группе событий. Разбираем, чем отличаются system, content, user и другие типы, когда срабатывать на onContentPrepare, а когда выбрать событие сохранения.

В Joomla один и тот же код можно попытаться разместить в шаблоне, компоненте или плагине — и получить три разных результата. Плагин работает только внутри своей группы и вызывается в определённый момент жизненного цикла приложения. Ошибка в выборе типа или события приводит к тому, что обработчик не запускается, срабатывает слишком часто или ломает административную часть сайта. Ниже — практическая карта плагинов Joomla 5.x: какой тип выбрать, где искать событие и что проверить, если расширение молчит.
Как Joomla разделяет плагины
У плагина есть две независимые характеристики: группа и событие. Группа определяет область работы, а событие — конкретный момент, когда Joomla передаёт управление обработчику.
Например, system-плагин может реагировать на запуск приложения, маршрутизацию и завершение запроса. content-плагин предназначен для обработки материалов. Это не одно и то же: обработчик события контента не станет системным только потому, что его включили в панели администратора.
Правильный вопрос при создании плагина звучит не «где написать этот код», а «какой объект Joomla должен уведомить меня и в какой момент».
Основные типы плагинов Joomla 5.x
| Группа | Для чего подходит | Типичные события или задачи |
|---|---|---|
| system | Общие действия на всём сайте и в админке | Инициализация, маршрутизация, добавление общих проверок и подключение ресурсов |
| content | Материалы и их отображение | Изменение текста перед выводом, реакция на создание или сохранение материала |
| user | Пользователи и их жизненный цикл | Регистрация, вход, изменение и сохранение данных пользователя |
| authentication | Проверка учётных данных | Подключение внешнего источника аутентификации |
| editors | Интеграция визуального редактора | Добавление редактора и настройка его поведения |
| editors-xtd | Кнопки и дополнительные действия рядом с редактором | Вставка специальных элементов в поле материала |
| fields | Дополнительные типы полей | Отображение и обработка собственного поля в формах |
| finder | Индексация для умного поиска | Передача поисковому индексу данных расширения |
| extension | Реакция на установку, обновление или удаление расширений | Синхронизация данных после изменения расширения |
| file | Проверка или обработка файлов | Действия, связанные с файловыми операциями |
| quickicon | Иконки уведомлений на панели управления | Добавление собственного индикатора или ссылки |
| webservices | Расширение API Joomla | Подключение маршрутов и обработчиков веб-сервисов |
| workflow | Рабочие процессы материалов и других сущностей | Интеграция с этапами и переходами workflow |
Набор групп зависит от версии Joomla и установленных расширений. В панели управления названия могут отображаться с переводом, но техническая группа плагина задаётся в его манифесте и должна совпадать с ожидаемым типом.
Событие — уведомление от Joomla или расширения о том, что произошло определённое действие: приложение запустилось, материал готовится к выводу, пользователь сохранён. Обработчик — метод или подписчик, который принимает это уведомление.
Как выбрать группу плагина
System: код, которому нужен весь запрос
Выбирайте system, если логика не принадлежит одному компоненту или типу данных. Это могут быть проверка заголовка запроса, общая интеграция, подключение JavaScript для всех страниц или реакция на запуск приложения.
Цена универсальности — риск выполнить код слишком часто. System-плагин может запускаться в административной панели, на сайте, в CLI-запросе и во время AJAX-операции. Перед тяжёлой логикой проверяйте контекст приложения и тип запроса.
Content: изменение материала, а не всей страницы
Content-плагин подходит для подстановки разметки в текст материала, фильтрации содержимого и реакции на сохранение статьи. Это лучший вариант для логики, которая должна работать с объектом материала, но не должна вмешиваться в каждый запрос.
Событие подготовки контента может вызываться несколько раз для одной страницы: отдельно для модулей, списка материалов и полного текста. Поэтому обработчик должен быть идемпотентным — повторный запуск не должен добавлять один и тот же блок снова.
User: не путайте вход и изменение профиля
User-плагин нужен для реакций на операции с пользователями. Но вход в систему, создание учётной записи и сохранение профиля — разные этапы. Подключение к событию сохранения не означает, что обработчик будет вызван при каждой авторизации.
Если задача связана с проверкой пароля во внешней системе, смотрите в сторону authentication. Если нужно отправить уведомление после изменения профиля, обычно нужен user-плагин и событие сохранения пользователя.
Специализированные группы
Группы editors, fields, finder, webservices и workflow стоит выбирать, когда Joomla уже описывает задачу отдельным контрактом. Такой плагин понятнее системе и другим разработчикам, чем универсальный system-плагин с десятками проверок.
Например, новый тип поля не следует реализовывать через подмену HTML в content-плагине. Поле должно участвовать в форме и сохраняться как поле. Аналогично, интеграцию с умным поиском лучше строить через finder, а не запускать собственный индексатор на каждой загрузке страницы.
Как выбрать событие
- Опишите объект, с которым работает код. Это приложение, материал, пользователь, файл, расширение или поисковый индекс. Если объект не определён, вы почти наверняка смотрите на system-событие слишком широко.
- Определите момент. Нужна подготовка данных до вывода, реакция после сохранения или изменение результата операции. События до и после действия нельзя менять местами: после сохранения у вас уже могут отсутствовать исходные значения.
- Проверьте контекст. Один и тот же обработчик может запускаться на сайте, в админке и из CLI. Для каждого сценария решите, должен ли он работать.
- Найдите документацию именно для Joomla 5.x. Имена событий и типы аргументов нужно сверять с документацией события или исходным кодом ядра. Старый пример для Joomla 3 может использовать устаревший стиль обработчика.
- Проверьте повторный запуск. Откройте страницу со списком материалов, полный материал и форму редактирования. Если логика добавляет данные дважды, событие выбрано слишком широко или обработчик не защищён от повторной обработки.
Старый стиль обработчиков и подписчики событий
В старых примерах Joomla-обработчик часто выглядит как публичный метод с именем события: например, метод для onContentPrepare. Такой код всё ещё встречается в расширениях, но переносить пример из Joomla 3 в Joomla 5.x без проверки нельзя.
В актуальном подходе Joomla используется система событий, а расширение может объявлять подписку через SubscriberInterface. У событий могут быть типизированные объекты, например объект события контента, из которого получают контекст и данные. Сигнатуру нельзя угадывать по названию метода: её проверяют в документации Joomla или в исходном коде соответствующего класса события.
Практическое правило простое: если вы поддерживаете существующий плагин, сначала сохраните совместимость с его контрактом. Если пишете новый плагин под Joomla 5.x, ориентируйтесь на актуальную документацию событий и не копируйте метод из расширения для Joomla 3 без адаптации.
Что ломается чаще всего
Плагин включён, но ничего не происходит
Проверьте группу и порядок публикации. Плагин content не получит системное событие, если он объявлен не в той группе. Затем включите отладку Joomla и убедитесь, что код вообще достигает обработчика. Логика внутри метода может быть безошибочной, но событие в выбранном сценарии не вызывается.
Код срабатывает дважды
Это особенно часто происходит с обработчиками контента. Один материал может участвовать в нескольких этапах формирования страницы. Добавьте проверку входных данных и признак уже обработанного объекта, а не рассчитывайте на то, что Joomla вызовет событие только один раз.
Работает на сайте, но не в админке
Убедитесь, что код не зависит от объекта, который существует только в одном приложении. System-плагины могут запускаться в административной части и в консольных командах. Если обработка нужна только на сайте, ограничьте её после определения текущего приложения, используя API Joomla 5.x, а не проверку случайного URL-параметра.
После обновления Joomla появилась ошибка аргументов
Сравните сигнатуру обработчика с версией события. Переход от устаревшего метода к объекту события может требовать изменения не только имени класса, но и способа получения данных. Не исправляйте ошибку подбором аргументов наугад: найдите класс события в API-документации Joomla 5.x.
Когда плагин — неправильный выбор
Плагин не заменяет компонент. Если функция имеет собственные страницы, сложные формы, маршруты, таблицы и права доступа, компонент даст более ясную архитектуру. Модуль подходит для отдельного блока вывода, а шаблон — для представления. System-плагин удобен для склейки, но быстро превращается в скрытый компонент, если в нём появляется бизнес-логика магазина.
Отдельная тема — порядок выполнения нескольких плагинов и инвалидация кеша. Здесь важно не только событие, но и последовательность публикации расширений; разбор кеширования выходит за рамки этой статьи.
Что делать дальше
Возьмите одну задачу и запишите её в формате «объект — момент — результат»: например, «материал — перед выводом — добавить метку». Затем выберите наиболее узкую группу, найдите событие для Joomla 5.x и протестируйте четыре сценария: сайт, админка, список материалов и одиночная страница. В продакшене смотрите не только на ошибки, но и на количество вызовов обработчика и время, которое он добавляет к запросу.
Автоэксперт / механик: Расшифровка OBD2-кодов, выбор б/у авто, диагностика по симптомам.
Спросить за 12 ₽Источники: Joomla Manual: Plugins, Joomla API Documentation: CMSPlugin
Частые вопросы
Можно ли сделать любой плагин system и проверять тип страницы внутри кода?
Почему onContentPrepare вызывается несколько раз для одного материала?
Что делать, если пример плагина рассчитан на Joomla 3, а у меня Joomla 5?
Почему опубликованный плагин не реагирует на событие?
Можно ли выполнять тяжёлый запрос к API внутри system-плагина?
Как понять, что выбранное событие подходит для сохранения данных?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.