> For the complete documentation index, see [llms.txt](https://docs.johncms.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.johncms.com/10.0/moduli/struktura-modulya.md).

# Структура модуля

Модули располагаются в папке **modules**, каждый — внутри папки своего вендора: `modules/<вендор>/<модуль>`. Всё, что поставляется вместе с CMS, лежит в `modules/johncms/`, а модуль стороннего разработчика — в папке с его именем, например `modules/mysite/partners`.

Такая раскладка позволяет двум разработчикам выпустить модуль с одинаковым названием, не сталкиваясь друг с другом.

Обязательного в структуре модуля немного: в корне модуля должен лежать манифест **module.php** — без него папка модулем не считается, — а конфигурация, шаблоны, переводы и миграции ищутся системой по соглашению, в папках `config`, `templates`, `locale` и `migrations`. Где лежат классы, решает сам модуль: путь объявляется в манифесте.

Начиная с версии **9.9** для кода рекомендуется слоистая структура: исходники в папке **src**, разделённые по слоям (Application, Domain, Infrastructure). Такая структура упрощает поддержку и рефакторинг больших модулей.

Обычно модуль имеет следующую структуру:

* modules
  * vendor\_name
    * module\_name
      * module.php
      * config
      * locale
      * migrations
      * public
      * src
        * Application
        * Domain
        * Infrastructure
        * Install
      * templates

Давайте подробнее посмотрим на структуру и разберёмся, что и для чего предназначено.

* **modules** — это обычная системная папка с модулями.
  * **vendor\_name** — папка вендора (например johncms для модулей поставки).
    * **module\_name** — это папка с названием модуля (например forum, community и т.п.).
      * **module.php** — манифест модуля: ключ (`вендор/модуль`), короткое имя (`alias`), название и пространство имён классов. Без него папка модулем не считается.
      * **config** — конфигурация модуля: маршруты (`routes.php`) и регистрация сервисов в контейнере (`services.php`).
      * **locale** — папка, в которой хранятся файлы локализации модуля. Если модуль мультиязычный, то эта папка обычно есть.
      * **migrations** — миграции модуля: его таблицы описаны здесь и больше нигде (см. [Миграции базы данных](/10.0/baza-dannykh/migracii.md)).
      * **public** — собранные стили, скрипты и картинки модуля. При установке копируются в document root, в `public/modules/<алиас>/` (см. [Публикация модуля](/10.0/moduli/publikaciya-modulya.md)).
      * **src** — исходный код модуля, разделённый по слоям.
        * **Application** — прикладной слой: контроллеры (`Controllers`), сценарии использования (`UseCases`), объекты передачи данных (`DTO`), сервисы (`Services`), middleware (`Middlewares`), консольные команды (`Console`), исключения (`Exceptions`).
        * **Domain** — доменный слой: модели (`Models`), контракты репозиториев (`Repository`), сущности (`Entities`), перечисления (`Enums`).
        * **Infrastructure** — инфраструктурный слой: реализации репозиториев и работа с хранилищем данных (`Persistence/Repository`).
        * **Install** — `Installer.php` с демонстрационными данными модуля. Таблицы он не создаёт: за них отвечают миграции.
      * **templates** — в этой папке хранятся шаблоны модуля: публичные страницы в `public`, страницы панели администратора — в `admin`.

{% hint style="info" %}
Вложенные папки внутри `src` (например `Controllers`, `UseCases`, `Repository`) создаются по мере необходимости — только когда в них появляется первый класс. Заранее создавать все папки не нужно.
{% endhint %}

Модуль, который распространяется через composer, несёт рядом с манифестом ещё и свой `composer.json` — об этом в статье [Публикация модуля](/10.0/moduli/publikaciya-modulya.md).

## Автозагрузка классов

Классы модуля загружаются по стандарту PSR-4, а пространство имён и папка, которой оно соответствует, объявляются в манифесте:

{% code title="modules/vendor\_name/module\_name/module.php" %}

```php
'autoload' => ['psr-4' => ['Vendor\\ModuleName\\' => 'src/']],
```

{% endcode %}

Путь указывается относительно папки модуля, поэтому одинаково работает и для модуля в `modules/`, и для модуля, установленного composer'ом в `vendor/`. Классы регистрируются при загрузке модуля — `composer dump-autoload` выполнять не нужно, а выключённый модуль перестаёт быть видимым и для автозагрузчика.

{% hint style="info" %}
У модулей поставки поля `autoload` в манифесте нет: их пространства имён (`Johncms\Modules\…`) объявлены в корневом `composer.json`, где composer собирает из них оптимизированную карту классов. Стороннему модулю туда нельзя — этот файл принадлежит поставке CMS и перезаписывается при обновлении.
{% endhint %}

Формально `autoload` может указывать на любую папку внутри модуля, в том числе на его корень — так автозагружаются модули, написанные до 9.8, у которых папки `Controllers` и `Install` лежат прямо в корне. Для новых модулей используйте `src/` и слоистую структуру, описанную выше.
