# Создание модуля

Давайте создадим свой первый простой модуль.\
Это будет обычная простая страница контактов для связи с администрацией сайта.

Как нам уже известно, модули располагаются в папке **modules**

Сначала давайте создадим папку с модулем и назовем её **contacts** путь к папке получится такой: **modules/contacts**

Пока создадим простой модуль без мультиязычности.

Внутри папки **modules/contacts** создадим подпапку **templates** для шаблона нашей страницы.\
Так же создадим папку **Controllers** для контроллеров. \
После выполнения этих действий у вас должна получиться такая структура:

![Структура папок модуля для JohnCMS](/files/-MVfvjxpMy77bFECuF_8)

Дополнительные папки нам больше не понадобятся.

Начиная с JohnCMS 9.4 появилась возможность использовать контроллеры. Контроллеры позволяют избавиться от большого количества базового кода, который необходимо написать для начала работы, а так же позволяют упростить настройку маршрутов и не писать самостоятельно логику по определению страницы, которую необходимо показать пользователю.

Контроллеры являются обычными php классами которые наследуют системный класс контроллера. В JohnCMS используется автозагрузка классов модулей. Чтобы она работала, нужно придерживаться некоторых правил:

1. Классы модуля должны располагаться в папке с модулем, а [пространство имен](https://www.php.net/manual/ru/language.namespaces.rationale.php) должно быть именем папки модуля с заглавной буквы. Разрешено использовать любые директории в папке с модулем для логического разделения классов.
2. Для работы автозагрузки классов модуль должен быть зарегистрирован в системе. Как это сделать рассмотрим ниже.

## Регистрация модуля

Для работы автозагрузки классов модули необходимо регистрировать в системе. Делается это с помощью конфигурационного файла.

Создайте в папке **config/autoload** файл с именем **modules.local.php** и следующим содержимым

{% code title="/config/autoload/modules.local.php" %}

```php
<?php

return [
    'modules' => [
        'installed_modules' => [
            'contacts', // Название папки с модулем
        ],
    ],
];

```

{% endcode %}

В данном случае contacts это название папки с модулем. При добавлении дополнительных модулей просто добавьте их названия по аналогии с этим именем.\
После выполнения этих действий классы вашего модуля будут загружаться автоматически если их пространство имен это название папки с вашим модулем с заглавной буквы.

В нашем случае пространством имен будет **Contacts**

## Создание контроллера

Создадим наш первый контроллер, который будет отвечать за отображение страницы контактов.

Исходя из типовой [структуры модуля](/9.7/moduli/struktura-modulya.md) классы контроллеров должны располагаться в папке Controllers\
Эта папка будет пространством имен для контроллеров. С учетом того, что модуль имеет пространство имен Contacts а папка Controllers расположена в модуле, то пространство имен для нашего контроллера будет такое: `Contacts\Controllers`

Контроллеры модуля должны наследовать `Johncms\Controller\BaseController`

Давайте наконец создадим наш контроллер. Создадим файл ContactsController.php со следующим содержимым:

{% code title="modules/contacts/Controllers/ContactsController.php" %}

```php
<?php

namespace Contacts\Controllers;

use Johncms\Controller\BaseController;

class ContactsController extends BaseController
{
    public function index()
    {
    }
}
```

{% endcode %}

&#x20;Это минимальный набор кода, который понадобится для работы.

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

Для автоматической базовой настройки шаблонизатора и загрузки файлов локализации нам понадобится добавить свойство $module\_name с названием папки модуля (в нашем случае contacts).

```php
protected $module_name = 'contacts';
```

Теперь нам нужно дополнить метод **index**.

Далее давайте установим заголовок страницы в тегах title и h1. Для этого в шаблонизатор нужно добавить 2 переменные с именем title и page\_title. Делается это следующим образом:

```php
// Устанавливаем заголовок страницы в теге title и h1
$this->render->addData(
    [
        'title'      => 'Контакты',
        'page_title' => 'Наши контакты',
    ]
);
```

Далее нам нужно добавить нашу страницу в цепочку навигации.

```php
$this->nav_chain->add('Контакты', '/contacts/');
```

Теперь нам нужно подготовить данные для шаблона. Давайте просто наполним один массив нашими контактами и передадим его в шаблон

```php
// Собираем массив данных, который будет передан в шаблон
$data = [
    'contacts' => [
        [
            'name'  => 'E-mail', // Название контакта
            'value' => 'admin@example.com', // Значение, которое будет отображаться
        ],
        [
            'name'  => 'Номер телефона',
            'value' => '+7 (999) 121-12-21',
        ],
        [
            'name'  => 'Telegram',
            'value' => '@johncms_official',
        ],
    ],
];

return $this->render->render('contacts::index', ['data' => $data]);
```

Обратите внимание на последнюю строку. Шаблонизатор так же имеет свое пространство имен для шаблонов. Оно автоматически регистрируется в базовом контроллере и является названием папки с модулем. В нашем случае **contacts** это название нашего модуля, а **index** это название файла шаблона из папки **templates**. Вторым параметром `['data' => $data]` передается массив данных, которые будут доступны в шаблоне. Ключи этого массива будут использоваться как названия переменных, а значения в качестве значений. В данном примере в шаблоне у нас будет доступна переменная data и она будет содержать массив с контактными данными.

### Полный код файла контроллера

{% code title="modules/contacts/Controllers/ContactsController.php" %}

```php
<?php

namespace Contacts\Controllers;

use Johncms\Controller\BaseController;

class ContactsController extends BaseController
{
    protected $module_name = 'contacts';

    public function index()
    {
        // Устанавливаем заголовок страницы в теге title и h1
        $this->render->addData(
            [
                'title'      => 'Контакты',
                'page_title' => 'Наши контакты',
            ]
        );

        // Добавляем страницу в цепочку навигации
        $this->nav_chain->add('Контакты', '/contacts/');

        // Собираем массив данных, который будет передан в шаблон
        $data = [
            'contacts' => [
                [
                    'name'  => 'E-mail', // Название контакта
                    'value' => 'admin@example.com', // Значение, которое будет отображаться
                ],
                [
                    'name'  => 'Номер телефона',
                    'value' => '+7 (999) 121-12-21',
                ],
                [
                    'name'  => 'Telegram',
                    'value' => '@johncms_official',
                ],
            ],
        ];

        return $this->render->render('contacts::index', ['data' => $data]);
    }
}

```

{% endcode %}

## Создание шаблона

Далее давайте создадим наш шаблон. Шаблон будет располагаться в папке **templates** и т.к. это основная страница контактов, назовем шаблон **index.phtml**

{% code title="modules/contacts/templates/index.phtml" %}

```php
<?php
// Подключаем основной шаблон сайта
$this->layout('system::layout/default');
?>

<div>
    Вы можете связаться с нами по любому из нижеперечисленных контактов:
</div>

<ul>
    <!-- Тут мы перебираем наш массив контактов и выводим название контакта и значение, разделяя их двоеточием -->
    <?php foreach ($data['contacts'] as $contact): ?>
        <li><?= $contact['name'] ?>: <b><?= $contact['value'] ?></b></li>
    <?php endforeach; ?>
</ul>
```

{% endcode %}

## Добавление маршрута

Наш модуль готов, но пока ещё не доступен в браузере. Давайте это исправим.\
Чтобы модуль стал доступен, нужно сообщить системе, что у нас есть такой модуль и мы хотим чтобы он был доступен по определенному адресу.\
Для этого давайте перейдем в папку **config** и в ней создадим файл **routes.local.php** если его ещё нет. Если есть, то откроем его и добавим маршрут для нашего модуля.

```php
<?php

/**
 * /contacts/ - Это адрес страницы по которому будет доступен наш модуль
 *
 * [\Contacts\Controllers\ContactsController::class, 'index']
 * Первое значение это класс контроллера, а второй название метода контроллера
 */
$map->addRoute(['GET', 'POST'], '/contacts[/]', [\Contacts\Controllers\ContactsController::class, 'index']);
```

Теперь наш модуль доступен по адресу **ваш.сайт/contacts/**

![Внешний вид итоговой страницы модуля контактов](/files/-MVg9rGwjnr6Z4IVSPEF)

Теперь давайте сообщим модулю online, что у нас появился модуль контактов и нужно в списке пользователей онлайн отображать тех, кто смотрит контакты.\
Для этого давайте перейдем в папку **config** и в ней создадим файл **places.local.php** если его ещё нет.

```php
<?php

return [
    '/contacts' => '<a href="/contacts/">Смотрит контакты</a>',
];
```

Отлично, наш модуль теперь полностью работоспособен, вам останется только добавить на него ссылку в основном шаблоне или на любой другой странице на ваше усмотрение.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.johncms.com/9.7/moduli/sozdanie-modulya.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
