Компонент Joomla: структура и разработка с нуля
Компонент в Joomla 5 — это не один PHP-файл, а отдельное расширение с клиентской и административной частями, MVC-слоем и сервисами. Показываем структуру, границы слоёв и минимальный путь от файлов до страницы.

Компонент Joomla 5.x отвечает за основное содержимое страницы: список материалов, каталог товаров, форму заказа или личный кабинет. Ошибка в структуре быстро превращается в 404, пустой экран или класс, который Joomla не может загрузить. Ниже — практический разбор современного компонента с пространствами имён, MVC и отдельными частями для сайта и панели администратора.
Из чего состоит компонент Joomla
Компонент состоит как минимум из двух контекстов: site для публичной части и administrator для панели управления. У каждого контекста свои контроллеры, модели, представления и шаблоны. В Joomla 4 и 5 старый подход с глобальными классами и файлами вроде controller.php постепенно заменён структурой с PSR-4 и пространствами имён.
com_books/
├── administrator/
│ ├── services/
│ │ └── provider.php
│ ├── src/
│ │ ├── Controller/
│ │ │ └── DisplayController.php
│ │ ├── Model/
│ │ └── View/
│ └── tmpl/
├── site/
│ ├── src/
│ │ ├── Controller/
│ │ ├── Model/
│ │ └── View/
│ └── tmpl/
└── com_books.xml
PSR-4 — правило автозагрузки, при котором пространство имён класса соответствует пути к файлу. Например, класс Acme\Component\Books\Site\Model\BooksModel должен находиться в файле site/src/Model/BooksModel.php, если это соответствие описано в манифесте расширения.
Компонент лучше проектировать от маршрута и сценария пользователя, а не от набора PHP-файлов. Сначала определите, какую страницу Joomla должна открыть, затем разложите её на controller, model, view и template.
Границы site и administrator
Публичная часть показывает данные посетителю. Административная — изменяет их, запускает фильтрацию, массовые операции и настройки. Смешивать эти контексты не стоит: административную модель не нужно вызывать из публичного шаблона, а шаблон сайта не должен зависеть от пути внутри administrator.
| Часть | Задача | Типичные каталоги |
|---|---|---|
| site | Страница каталога, карточка записи, форма для посетителя | site/src, site/tmpl |
| administrator | Список записей, редактирование, настройки компонента | administrator/src, administrator/tmpl |
| services | Регистрация компонента в контейнере Joomla | administrator/services/provider.php |
| manifest | Описание и установка расширения | com_books.xml |
В Joomla 5.x не следует копировать структуру старых компонентов Joomla 3 без проверки. Она может использовать устаревший загрузчик, глобальные классы и другой способ входа в компонент.
Манифест: точка установки
Joomla читает XML-манифест, чтобы понять имя компонента, его namespace и состав файлов. Ниже — сокращённый пример для компонента com_books. Он показывает структуру, но не заменяет полный установочный пакет: для реального расширения понадобятся локализация, права доступа и файлы сервисного провайдера.
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" method="upgrade">
<name>com_books</name>
<author>Acme</author>
<version>1.0.0</version>
<description>COM_BOOKS_XML_DESCRIPTION</description>
<namespace path="src">Acme\Component\Books</namespace>
<files folder="site">
<folder>src</folder>
<folder>tmpl</folder>
</files>
<administration>
<menu>COM_BOOKS</menu>
<files folder="administrator">
<folder>services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
</administration>
</extension>
Значение path="src" относится к каждой части, указанной в манифесте. Поэтому пространство имён и каталоги нужно согласовать заранее. Если класс назван в namespace Acme\Component\Books\Administrator, его файл должен лежать внутри административного src, а не в произвольной папке компонента.
Как проходит запрос к компоненту
Пользователь открывает пункт меню, связанный с компонентом. Joomla определяет расширение, выбирает контроллер, передаёт ему задачу и получает представление. В типичном сценарии порядок выглядит так:
- Маршрутизация. Joomla определяет компонент по пункту меню и параметрам URL. Проверка: пункт меню открывает нужный компонент, а не стандартную страницу ошибки.
- Контроллер. Он принимает задачу и решает, какое представление показать или какое действие выполнить. Проверка: при открытии страницы вызывается ожидаемый controller, а не случайный класс из другого расширения.
- Модель. Она получает данные из базы или другого источника. Проверка: запрос возвращает данные в ожидаемом формате, а не HTML, сформированный внутри модели.
- Представление. Оно связывает модель с шаблоном. Проверка: Joomla находит view и не показывает ошибку о ненайденном layout.
- Шаблон. Файл в
tmplвыводит HTML. Проверка: в исходном коде страницы есть ожидаемая разметка, а экранирование пользовательских значений не пропущено.
Минимальный controller в Joomla 5.x
Для стартовой страницы компонента обычно достаточно контроллера, наследующего BaseController. В административной части namespace содержит сегмент Administrator.
<?php
namespace Acme\Component\Books\Administrator\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\BaseController;
final class DisplayController extends BaseController
{
}
Пустой класс не содержит бизнес-логики. Это намеренно: контроллер не должен превращаться в место для SQL-запросов, форматирования HTML и проверки всех полей формы одновременно. Для сложной операции создайте отдельную задачу контроллера, вынесите выборку в модель, а вывод оставьте шаблону.
Модель и запрос к базе
Для списка записей используется модель, которая строит запрос через API базы данных Joomla. Название таблицы ниже условное: она должна существовать в схеме вашего расширения. В реальном компоненте добавьте фильтры, сортировку, проверку доступа и постраничный вывод.
<?php
namespace Acme\Component\Books\Administrator\Model;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Model\ListModel;
final class BooksModel extends ListModel
{
protected function getListQuery()
{
$db = $this->getDatabase();
return $db->getQuery(true)
->select([
$db->quoteName('id'),
$db->quoteName('title'),
$db->quoteName('published'),
])
->from($db->quoteName('#__books'))
->order($db->quoteName('title') . ' ASC');
}
}
Префикс #__ Joomla заменяет на префикс базы данных сайта. Не подставляйте имя таблицы из пользовательского ввода. Значения фильтров также нельзя склеивать в SQL-строку: используйте параметры запроса и методы экранирования, предусмотренные API Joomla.
Два подхода к разработке
Для нового компонента выбор обычно сводится к двум стратегиям: писать расширение в современной namespaced-структуре или переносить старый компонент. У каждой есть цена.
| Подход | Когда подходит | Цена решения |
|---|---|---|
| Современный компонент Joomla 4/5 | Новый проект, долгий срок поддержки, собственная MVC-архитектура | Нужно разобраться с manifest, namespace, services и DI |
| Адаптация старого компонента | Есть рабочее расширение, которое требуется сохранить | Придётся проверять устаревшие API, загрузчик классов, SQL и совместимость шаблонов |
Для нового проекта выбирайте современную структуру. Миграция оправдана, когда уже есть данные, пользователи и бизнес-логика, которую нельзя быстро переписать. Не смешивайте оба подхода в одном классе: переходный код лучше изолировать и постепенно заменять.
Что ломается первым
- 404 после установки. Проверьте пункт меню и alias. Установка компонента сама по себе не создаёт публичный маршрут.
- Class not found. Сверьте namespace, регистр букв в имени файла и путь относительно
src. На Linux регистр важен. - Пустой список. Проверьте SQL, наличие таблицы с префиксом Joomla и права базы данных. Сначала выполните запрос на тестовой записи.
- Работает в админке, но не на сайте. У site и administrator разные namespace, модели и шаблоны. Нельзя считать их взаимозаменяемыми.
- Изменения не видны. Очистите кеш Joomla и проверьте, что редактируете установленный пакет, а не исходную копию в другом каталоге.
Где подход ломается
Простая MVC-схема перестаёт быть достаточной, когда компонент получает сложные права доступа, фоновые задачи, импорт больших файлов или интеграцию с внешним API. Не переносите такие операции в шаблон или один огромный controller. Вынесите доменную логику в отдельные классы, ограничьте время выполнения импорта и логируйте внешний ответ без секретов.
Отдельная тема — маршрутизация SEF-URL и инвалидация кеша. Они зависят от конкретного сценария компонента, поэтому здесь их не разворачиваем.
Что делать дальше
Соберите минимальный компонент, установите его на копию сайта Joomla 5.x и сначала добейтесь одного результата: пункт меню открывает view, а view получает одну запись из модели. Затем добавьте форму, проверку прав доступа и тесты для SQL-запросов. На проде следите за временем запросов, количеством обращений к базе и журналом ошибок Joomla — именно эти показатели раньше всего показывают, что компонент вырос из учебного примера в источник проблем.
Саммаризатор: 50 страниц или созвон — в 5 главных тезисов.
Спросить за 15 ₽Источники: Joomla Manual: Components, Joomla Manual: Extensions
Частые вопросы
Нужен ли компонент, если достаточно модуля Joomla?
Можно ли использовать один controller для site и administrator?
Почему Joomla не находит класс, хотя файл существует?
Можно ли разрабатывать компонент сразу для Joomla 4 и Joomla 5?
Что делать, если после установки открывается 404?
Безопасно ли писать SQL-запросы прямо в модели?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.