Свой модуль в Joomla: рабочие приёмы без хрупких костылей
В Joomla пользовательский HTML-модуль подходит для простого текста, но не для логики и запросов к данным. Разбираем, как устроить собственный модуль для Joomla 5.x, где держать код, как выводить параметры и что проверить перед публикацией.

Если вставить PHP в стандартный пользовательский HTML-модуль Joomla, код не станет приложением: редактор сохранит его как текст или удалит часть разметки. Для динамического блока нужен собственный модуль с manifest-файлом, точкой входа и шаблоном вывода. Ниже — рабочая схема для Joomla 5.x, варианты организации кода и ошибки, из-за которых модуль ломается после обновления.
Сначала выберите границу модуля
Модуль в Joomla — это небольшой блок, который движок размещает в позиции шаблона: меню, уведомление, список записей, форму или виджет. Он не должен превращаться в мини-компонент с собственной админкой, маршрутизацией и десятками экранов. Если пользователь должен управлять отдельными сущностями, смотреть их списки и открывать страницы объектов, обычно нужен компонент, а не модуль.
Для собственного модуля на Joomla 5.x заранее определите три вещи:
- какие данные он получает: только параметры, запрос к базе или данные внешнего сервиса;
- где выполняется логика: в точке входа, отдельном helper-классе или сервисе;
- какой результат должен появиться в HTML: один шаблон или несколько вариантов layout.
Главное правило модуля: получить данные в PHP, а разметку оставить шаблону. Тогда изменение HTML не заставит переписывать запросы и условия.
Layout — файл шаблона, который отвечает за HTML-вывод модуля. В Joomla его можно заменить переопределением в шаблоне сайта, не изменяя файлы расширения.
Три подхода к собственному модулю
| Подход | Когда использовать | Цена решения |
|---|---|---|
| Пользовательский HTML-модуль | Текст, ссылки, заранее известная разметка | Нет PHP-логики и безопасной обработки данных |
| Модуль с параметрами и шаблоном | Настраиваемый блок без сложного источника данных | Нужно собрать и установить собственное расширение |
| Модуль с helper-классом | Запросы к базе, фильтрация, подготовка списка | Появляются зависимости, кеширование и вопросы производительности |
| Модуль, использующий сервис | Сложная логика или повторное использование кода | Выше порог входа и больше файлов |
Для первого рабочего блока обычно достаточно второго варианта. Не выносите в helper одну строку, которая читает параметр. Но и не складывайте запросы, форматирование и HTML в один файл: такой модуль быстро становится непредсказуемым.
Минимальная структура модуля
Назовём расширение mod_notice. Для Joomla 5.x минимальный пакет может выглядеть так:
mod_notice/
├── mod_notice.php
├── mod_notice.xml
└── tmpl/
└── default.php
Имя модуля должно начинаться с префикса mod_. Он используется в имени папки, PHP-файла и manifest-файла. Несовпадение в одном символе приводит к ошибке установки или к пустому выводу.
Manifest-файл
Файл mod_notice.xml описывает расширение и его параметры. Пример рассчитан на Joomla 5.x:
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" client="site" method="upgrade">
<name>MOD_NOTICE</name>
<version>1.0.0</version>
<author>Site team</author>
<description>Simple notice module</description>
<files>
<filename module="mod_notice">mod_notice.php</filename>
<folder>tmpl</folder>
</files>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="text"
type="textarea"
label="Текст уведомления"
filter="safehtml"
rows="5"
/>
</fieldset>
</fields>
</config>
</extension>
В элементе filename атрибут module должен совпадать с именем PHP-файла без расширения. Поле text появится в настройках экземпляра модуля, а не в отдельной глобальной панели.
Точка входа и layout
В mod_notice.php не выводите разметку напрямую. Получите параметр и передайте управление шаблону:
<?php
defined('_JEXEC') or die;
use Joomla\CMS\Helper\ModuleHelper;
require ModuleHelper::getLayoutPath(
'mod_notice',
$params->get('layout', 'default')
);
В tmpl/default.php экранируйте значение перед выводом:
<?php
defined('_JEXEC') or die;
$noticeText = (string) $params->get('text', '');
?>
<div class="mod-notice" role="note">
<?php echo htmlspecialchars($noticeText, ENT_QUOTES, 'UTF-8'); ?>
</div>
После установки архива откройте раздел модулей, создайте экземпляр mod_notice, выберите позицию, назначьте пункты меню и задайте текст. Проверка проста: на выбранной странице появляется один блок mod-notice, а в исходном HTML нет неэкранированных кавычек из параметра.
Как добавлять данные, а не только текст
Если модулю нужен список, не помещайте SQL-запрос в default.php. Шаблон должен знать о готовом массиве, но не о таблицах и условиях выборки.
Для небольшого модуля можно использовать helper-файл. В точке входа:
<?php
defined('_JEXEC') or die;
use Joomla\CMS\Helper\ModuleHelper;
require_once __DIR__ . '/helper.php';
$items = ModNoticeHelper::getItems($params);
require ModuleHelper::getLayoutPath(
'mod_notice',
$params->get('layout', 'default')
);
Helper должен возвращать данные, а не HTML. Например, его метод может принять количество элементов и категорию из параметров, выполнить запрос через штатный слой базы Joomla и вернуть массив объектов. Точный запрос зависит от таблицы и схемы данных, поэтому не копируйте пример с чужими именами полей: сначала проверьте структуру базы и права пользователя подключения.
В шаблоне останется только вывод:
<?php
defined('_JEXEC') or die;
?>
<ul class="mod-notice__list">
<?php foreach ($items as $item) : ?>
<li>
<?php echo htmlspecialchars((string) $item->title, ENT_QUOTES, 'UTF-8'); ?>
</li>
<?php endforeach; ?>
</ul>
Если данные приходят из внешнего API, добавьте тайм-аут, обработку ошибки и кеширование. Запрос к сервису на каждый просмотр страницы — быстрый способ превратить задержку чужого сервера в задержку всего сайта.
Что ломается в реальном проекте
PHP оказался в пользовательском HTML-модуле
Такой модуль предназначен для контента, а не для исполнения серверного кода. Перенесите логику в расширение, а в админке оставьте только параметры, которые действительно должен менять контент-менеджер.
HTML выводится напрямую
Строка из параметров, базы или запроса не считается безопасной только потому, что её ввёл администратор. Для обычного текста используйте htmlspecialchars. Если параметр должен поддерживать ограниченный HTML, настройте допустимый фильтр и отдельно проверьте, что он не пропускает опасные атрибуты.
Модуль работает в одной позиции и исчезает в другой
Проверьте три уровня: существует ли позиция в активном шаблоне, назначен ли модуль нужным пунктам меню и не скрывает ли его CSS-класс шаблона. В Joomla позиция — это не универсальная координата: каждый шаблон объявляет свой набор мест для вывода.
После изменения PHP сайт показывает ошибку
Сначала включите режим отладки только на тестовом сайте и посмотрите журнал PHP. Затем проверьте синтаксис, имя класса и путь к файлу. Не копируйте старый код модуля из Joomla 3.x без проверки: в Joomla 4.x и 5.x расширения постепенно переходят на пространства имён и современные классы.
Кеш показывает старые данные
У модуля может быть собственный кеш, а у сайта — кеш страницы или прокси перед Joomla. Если блок зависит от пользователя, языка, запроса или текущего времени, кеширование нужно проектировать отдельно. Иначе один посетитель увидит данные, подготовленные для другого.
Когда какой подход выбирать
Используйте пользовательский HTML-модуль, если редактор меняет только текст и ссылки. Собственный модуль с параметрами подходит для повторяемого блока, который нужно размещать в нескольких позициях или на разных страницах. Helper нужен, когда подготовка данных уже стала отдельной задачей. Сервисный слой оправдан, если эта логика используется не только одним модулем.
Не смешивайте инсталляцию и бизнес-логику. Manifest описывает состав пакета, точка входа собирает данные, layout выводит HTML. Такое разделение облегчает переопределение шаблона и уменьшает риск потерять изменения при обновлении расширения.
Что делать дальше
Установите модуль сначала на копию сайта и проверьте четыре сценария: параметр пустой, список не найден, внешний источник недоступен, кеш включён. Затем создайте переопределение layout в активном шаблоне и убедитесь, что обновление расширения не перезаписывает ваши изменения. В продакшене смотрите время ответа страницы, число запросов к базе и размер HTML, который добавляет модуль. Если эти показатели растут вместе с трафиком, следующим шагом будет настройка кеша и ограничение выборки, а не добавление новых условий в шаблон.
Создатель презентаций: Структура и текст каждого слайда: заголовки-утверждения, одна мысль на слайд, заметки докладчику.
Спросить за 150 ₽Источники: Joomla Documentation: Modules, Joomla Documentation: Layout Overrides
Частые вопросы
Можно ли сделать свой модуль только через админку Joomla?
Какая версия Joomla нужна для примеров?
Почему модуль установлен, но ничего не показывает?
Можно ли помещать SQL-запрос прямо в default.php?
Что будет, если модуль показывает устаревшие данные?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.