Версия: Joomla 5.4.5 — это релиз из серии 5.4.x, выпущенный в апреле 2026 года как исправление ошибок. Структура и соглашения, описанные здесь, применимы ко всем версиям Joomla 5.4.x.

Разработка компонентов в Joomla 5 следует архитектуре MVC (модель-представление-контроллер), но организация файлов принципиально отличается от Joomla 3: пространства имён — это ядро системы, пути и имена классов должны строго соответствовать друг другу, а ошибки в регистре на Linux приводят к тому, что класс не находится. Это руководство описывает все файлы и соглашения, необходимые для минимального работающего компонента, а в конце приведён готовый промпт для aider, который автоматизирует сборку установочного пакета.

1. Выбор пути разработки

Создать компонент Joomla 5 можно несколькими способами. Самый надёжный — вручную собрать минимальную структуру: без внешних генераторов и Node.js, вы полностью контролируете каждый файл. Альтернатива — Joomla Component Builder (JCB), графический генератор компонентов, устанавливаемый в Joomla, подходящий для быстрого создания CRUD. Есть также официальный туториал Joomla, шаг за шагом ведущий к полному компоненту. Для понимания внутренних механизмов Joomla 5 ручная сборка минимальной структуры — лучшая отправная точка.

2. Структура установочного пакета

Компонент Joomla должен быть упакован в .zip-архив, содержащий как минимум два каталога верхнего уровня: site/ (фронтенд) и admin/ (бэкенд). При установке Joomla копирует содержимое site/ в /components/com_имя, а admin/ — в /administrator/components/com_имя.

Дерево минимального компонента:

com_example/
├── example.xml                        # манифест
├── admin/
│   ├── services/
│   │   └── provider.php               # регистрация в DI-контейнере
│   ├── src/
│   │   ├── Extension/
│   │   │   └── ExampleComponent.php   # класс компонента
│   │   ├── Controller/
│   │   │   └── DisplayController.php  # контроллер по умолчанию
│   │   └── View/
│   │       └── Example/
│   │           └── HtmlView.php       # представление
│   ├── tmpl/
│   │   └── example/
│   │       └── default.php            # шаблон
│   └── language/
│       └── en-GB/
│           ├── com_example.ini
│           └── com_example.sys.ini
└── site/
    ├── src/
    │   ├── Controller/
    │   │   └── DisplayController.php
    │   └── View/
    │       └── Example/
    │           └── HtmlView.php
    ├── tmpl/
    │   └── example/
    │       └── default.php
    └── language/
        └── en-GB/
            └── com_example.ini

3. Манифест (Manifest)

Манифест сообщает Joomla: это компонент, вот его пространство имён, вот где лежат файлы. Ключевые элементы:

<extension type="component" method="upgrade">
    <name>example</name>
    <namespace path="src">MyCompany\Component\Example</namespace>
    <administration>
        <menu>COM_EXAMPLE</menu>
        <files folder="admin">
            <folder>services</folder>
            <folder>src</folder>
            <folder>tmpl</folder>
            <folder>language</folder>
        </files>
    </administration>
    <files folder="site">
        <folder>src</folder>
        <folder>tmpl</folder>
        <folder>language</folder>
    </files>
</extension>

Ключевой момент: значение <name> должно совпадать с именем компонента (без префикса com_) и обычно записывается в нижнем регистре. Если <name> в манифесте не совпадает с тем, что ожидает Joomla, может возникнуть ошибка «Invalid controller class: display». Атрибут path="src" в <namespace> указывает, что файлы классов лежат в подкаталоге src/ корня компонента; Joomla автоматически сгенерирует префиксы пространств имён \...\Administrator и \...\Site для бэкенда и фронтенда.

4. Соответствие пространств имён и путей

Joomla 5 использует PSR-4 автозагрузку. По префиксу пространства имён Joomla определяет каталог:

  • MyCompany\Component\Example\Administrator\ → administrator/components/com_example/src/
  • MyCompany\Component\Example\Site\ → components/com_example/src/

Это означает, что класс MyCompany\Component\Example\Administrator\Controller\DisplayController должен находиться в файле administrator/components/com_example/src/Controller/DisplayController.php. Регистр имён файлов и каталогов должен точно совпадать с пространством имён. Linux различает регистр: DisplayController.php и displaycontroller.php — разные файлы, и Joomla будет искать только первый.

5. Сервис-провайдер (provider.php)

admin/services/provider.php — мост между компонентом и DI-контейнером Joomla. Он регистрирует две фабрики: ComponentDispatcherFactory (создаёт диспетчер, а затем контроллеры) и MVCFactory (создаёт модели, представления, таблицы).

<?php
\defined('_JEXEC') or die;

use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
use Joomla\CMS\Extension\ComponentInterface;
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;

return new class implements ServiceProviderInterface
{
    public function register(Container $container)
    {
        $namespace = '\\MyCompany\\Component\\Example';

        $container->registerServiceProvider(new ComponentDispatcherFactory($namespace));
        $container->registerServiceProvider(new MVCFactory($namespace));

        $container->set(
            ComponentInterface::class,
            function (Container $container) {
                $component = new \MyCompany\Component\Example\Administrator\Extension\ExampleComponent(
                    $container->get(ComponentDispatcherFactoryInterface::class)
                );
                $component->setMVCFactory($container->get(MVCFactoryInterface::class));
                return $component;
            }
        );
    }
};

Самая частая ошибка: добавление суффикса \\Administrator к пространству имён, передаваемому в ComponentDispatcherFactory и MVCFactory. Эти фабрики принимают корневое пространство имён (\MyCompany\Component\Example) и сами добавляют Administrator или Site в зависимости от того, откуда пришёл запрос. Лишний \\Administrator заставит фабрику искать контроллеры в Administrator\Administrator\Controller, что приведёт к ошибке «Invalid controller class: display».

6. Класс компонента (Extension)

admin/src/Extension/ExampleComponent.php — главный класс компонента. Для минимального компонента достаточно унаследоваться от MVCComponent:

<?php
namespace MyCompany\Component\Example\Administrator\Extension;

use Joomla\CMS\Extension\MVCComponent;

class ExampleComponent extends MVCComponent
{
}

MVCComponent уже предоставляет базовую функциональность, необходимую диспетчеру. Переопределять boot() или реализовывать дополнительные интерфейсы нужно только тогда, когда компоненту требуются HTML-сервисы, сервисы категорий и т.п.

7. Контроллер (DisplayController)

Контроллер по умолчанию для бэкенда — admin/src/Controller/DisplayController.php. Он наследуется от BaseController и через $default_view указывает, какое представление использовать, когда параметр view не задан:

<?php
namespace MyCompany\Component\Example\Administrator\Controller;

use Joomla\CMS\MVC\Controller\BaseController;

class DisplayController extends BaseController
{
    protected $default_view = 'example';
}

Контроллер фронтенда имеет ту же структуру, только пространство имён — ...\Site\Controller. Когда URL имеет вид ?option=com_example (без параметра task), диспетчер Joomla создаёт DisplayController и вызывает его метод display() по умолчанию.

8. Представление (HtmlView)

Представление подготавливает данные и рендерит шаблон. admin/src/View/Example/HtmlView.php:

<?php
namespace MyCompany\Component\Example\Administrator\View\Example;

use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;

class HtmlView extends BaseHtmlView
{
    public function display($tpl = null)
    {
        $this->title = Text::_('COM_EXAMPLE_TITLE');
        parent::display($tpl);
    }
}

Имя класса представления должно соответствовать имени каталога и параметру view в запросе. Параметр view=example в URL заставит MVCFactory искать ...\View\Example\HtmlView.

9. Шаблон (default.php)

Шаблон — это чистый PHP/HTML-файл, расположенный в admin/tmpl/example/default.php (и в соответствующем site/tmpl/example/default.php для фронтенда):

<?php
\defined('_JEXEC') or die;
?>
<div class="container">
    <h1><?php echo $this->title; ?></h1>
    <p>Hello from com_example.</p>
</div>

Обратите внимание: шаблоны не находятся в src/, поэтому им не нужен namespace. \defined('_JEXEC') or die; в таких файлах без пространства имён допустим и рекомендуется.

10. Языковые файлы

Joomla выводит текст через языковые константы, а не хардкод строк. Языковые файлы бэкенда лежат в admin/language/en-GB/:

com_example.ini (используется в интерфейсе компонента):

COM_EXAMPLE_TITLE="Example Component"
COM_EXAMPLE_DESCRIPTION="A minimal Joomla 5 component."

com_example.sys.ini (используется Joomla для отображения имени и описания в менеджере расширений):

COM_EXAMPLE="Example"
COM_EXAMPLE_XML_DESCRIPTION="A minimal Joomla 5 component."

11. Ловушка с пространствами имён и defined('_JEXEC')

В PHP-файлах, содержащих объявление namespace, defined('_JEXEC') or die; не может стоять перед namespace. PHP требует, чтобы namespace был первым оператором в файле (кроме declare). Если вызвать defined() до namespace, возникнет фатальная ошибка: «Namespace declaration statement has to be the very first statement».

Правильный подход:

  • Файлы классов с пространством имён (в src/): ставьте \defined('_JEXEC') or die; после namespace и use, с обратным слешем перед defined.
  • Файлы шаблонов без пространства имён (в tmpl/): defined('_JEXEC') or die; можно ставить в начале файла.

12. Установка и кэш

Упаковав структуру в com_example.zip, установите её через бэкенд Joomla: System → Install → Extensions. Joomla скопирует файлы в нужные места и зарегистрирует компонент в таблице #__extensions.

После установки Joomla обновляет administrator/cache/autoload_psr4.php, сопоставляя префикс вашего пространства имён с путём в файловой системе. Если после установки компонент выдаёт «класс не найден» или «Invalid controller class», сначала проверьте, есть ли в этом файле запись для пространства имён вашего компонента. Если нет — удалите файл и обновите страницу, Joomla пересоздаст его. Также убедитесь, что плагин «Extension - Namespace Updater» включён — он отвечает за обновление этого кэша при установке/обновлении расширений.

13. Проверка работоспособности компонента

После установки в меню Components бэкенда должен появиться ваш компонент. Нажмите на него — если вы видите заголовок, выводимый шаблоном, значит вся цепочка (манифест → установка → DI-контейнер → диспетчер → контроллер → представление → шаблон) работает. Дальше можно добавлять модели, таблицы, формы и CRUD-контроллеры, размещая каждый новый класс в правильном каталоге src/ с правильным пространством имён.

14. Частые ошибки и их причины

СимптомПричина
«Invalid controller class: display»Лишний \\Administrator в ComponentDispatcherFactory/MVCFactory; несовпадение <name> в манифесте; устаревший autoload_psr4.php
«Namespace declaration statement has to be the very first statement»defined('_JEXEC') стоит перед namespace в файле класса
«Class not found»Регистр имени файла/каталога не совпадает с пространством имён; autoload_psr4.php не обновился
«Could not create directory» при установкеНет прав на запись в components/ или administrator/components/
Компонент установился, но не появился в менюНе указан <menu> в секции <administration> манифеста

15. Что дальше

Минимальный компонент — это фундамент. Следующие шаги: добавление модели и таблицы для работы с данными, создание форм (XML-формы в admin/src/Model/Forms/ или admin/forms/), CRUD-контроллеры, маршрутизация на фронтенде, права доступа (ACL). Каждый новый класс кладётся в соответствующий подкаталог src/ с пространством имён, соответствующим пути. Главное правило остаётся неизменным: пространство имён, путь к файлу и имя класса должны совпадать с точностью до регистра.

16. Промпт для aider: сборка установочного пакета

Когда компонент уже работает на живом сайте, его нужно упаковать в zip для повторной установки или резервной копии. Приведённый ниже промпт автоматизирует этот процесс через aider. Скопируйте его целиком в aider, запущенный из корня сайта Joomla.

Задача: создать установочный zip-пакет компонента Joomla 5.4.5 из уже работающих файлов на живом сайте.

Контекст:
- Компонент уже установлен и работает в Joomla 5.4.5.
- Корень сайта: /var/www/www-root/data/www/example.ru
- Имя компонента: com_example
- Namespace: MyCompany\Component\Example
- Рабочие файлы:
  - administrator/components/com_example/ (бэкенд)
  - components/com_example/ (фронтенд)
- Манифест: administrator/components/com_example/example.xml

Что нужно сделать:

1. Создать временную папку сборки:
   /var/www/www-root/data/www/example.ru/tmp/build_package

2. Внутри build_package создать структуру:
   build_package/
   ├── example.xml          (копия манифеста из administrator/components/com_example/)
   ├── admin/               (копия содержимого administrator/components/com_example/, БЕЗ example.xml)
   └── site/                (копия содержимого components/com_example/)

3. Удалить из build_package/admin/ файл example.xml, если он туда попал (манифест должен быть только в корне архива).

4. Проверить, что в build_package/example.xml:
   - <name>example</name> (нижний регистр, без com_)
   - <namespace path="src">MyCompany\Component\Example</namespace>
   - <files folder="admin"> и <files folder="site"> присутствуют

5. Проверить, что в build_package/admin/services/provider.php:
   - ComponentDispatcherFactory('\\MyCompany\\Component\\Example')
   - MVCFactory('\\MyCompany\\Component\\Example')
   - НЕТ суффикса \\Administrator в этих вызовах

6. Создать zip-архив:
   cd /var/www/www-root/data/www/example.ru/tmp/build_package
   zip -r /var/www/www-root/data/www/example.ru/tmp/com_example_package.zip .

7. Установить владельца архива:
   chown www-root:www-root /var/www/www-root/data/www/example.ru/tmp/com_example_package.zip

8. Проверить архив:
   unzip -l /var/www/www-root/data/www/example.ru/tmp/com_example_package.zip | head -40
   unzip -p /var/www/www-root/data/www/example.ru/tmp/com_example_package.zip example.xml | grep "<name>"

Ожидаемый результат:
- В корне архива только один example.xml
- <name>example</name>
- admin/ и site/ содержат все рабочие файлы
- Архив готов к установке через Upload Package File в админке Joomla

Не делай:
- Не добавляй defined('_JEXEC') перед namespace в файлах src/
- Не меняй namespace в файлах без необходимости
- Не добавляй \\Administrator в provider.php
- Не создавай дополнительных манифестов внутри admin/

После выполнения покажи:
- Список файлов в архиве (unzip -l)
- Значение <name> из манифеста в архиве
- Размер архива

Этот промпт фиксирует все места, где чаще всего возникают ошибки при упаковке компонента Joomla 5.4.5: дубликат манифеста внутри admin/, лишний \\Administrator в provider.php, неверный регистр в <name>. Его можно использовать и как чек-лист при ручной сборке.

Автор статьи: https://jedig.ru