Модулі

У Nette модулі являють собою логічні одиниці, з яких складається додаток. Вони включають ведучі, шаблони, можливо, компоненти та класи моделей.

Одного компонента для презентаторів і одного для шаблонів буде недостатньо для реальних проектів. Наявність десятків файлів в одній папці щонайменше неорганізована. Як вийти з цього становища? Ми просто розділяємо їх на підкаталоги на диску і на простори імен у коді. І це саме те, що роблять модулі Nette.

Тому давайте забудемо про єдину папку для ведучих і шаблонів і натомість створимо модулі, наприклад, Admin і Front.

app/
├── Presenters/
├── Modules/              ← директория с модулями
│   ├── Admin/            ← модуль Admin
│   │   ├── Presenters/   ← его презентеры
│   │   │   ├── DashboardPresenter.php
│   │   │   └── templates/
│   └── Front/            ← модуль Front
│       └── Presenters/   ← его презентеры
│           └── ...

Ця структура каталогів буде відображена в просторах імен класів, так, наприклад, DashboardPresenter буде знаходитися в просторі App\Modules\Admin\Presenters:

namespace App\Modules\Admin\Presenters;

class DashboardPresenter extends Nette\Application\UI\Presenter
{
	// ...
}

Ведучий Dashboard усередині модуля Admin позначається в додатку за допомогою подвійної точкової нотації як Admin:Dashboard, а його дія default позначається як Admin:Dashboard:default. А звідки Nette знає, що Admin:Dashboard представляє клас App\Modules\Admin\Presenters\DashboardPresenter? Ми говоримо про це, використовуючи відображення в конфігурації. Таким чином, наведена структура не є фіксованою, і ви можете змінювати її на свій розсуд.

Модулі, звісно, можуть містити всі інші частини, крім презентаторів і шаблонів, такі як компоненти, класи моделей тощо.

Вкладені модулі

Модулі не обов'язково повинні формувати тільки плоску структуру, ви також можете створювати, наприклад, підмодулі:

app/
├── Modules/              ← директория с модулями
│   ├── Blog/             ← модуль Blog
│   │   ├── Admin/        ← подмодуль Admin
│   │   │   ├── Presenters/
│   │   │   └── ...
│   │   └── Front/        ← подмодуль Front
│   │       ├── Presenters/
│   │       └── ...
│   ├── Forum/            ← модуль Forum
│   │   └── ...

Таким чином, модуль Blog розбивається на підмодулі Admin і Front. І знову ж таки це буде відображено в просторах імен, які будуть App\Modules\Blog\Admin\Presenters тощо. Ведучий Dashboard всередині підмодуля називається Blog:Admin:Dashboard.

Розгалуження може бути настільки глибоким, наскільки ви захочете, тому ви можете створювати підмодулі.

Посилання в шаблонах ведучого є відносними щодо поточного модуля. Таким чином, посилання Foo:default веде до ведучого Foo у тому ж модулі, що й поточний ведучий. Наприклад, якщо поточним модулем є Front, то посилання має такий вигляд:

<a n:href="Product:show">odkaz na Front:Product:show</a>

Посилання є відносним, навіть якщо ім'я модуля є його частиною, тоді він вважається підмодулем:

<a n:href="Shop:Product:show">odkaz na Front:Shop:Product:show</a>

Абсолютні посилання записуються аналогічно абсолютним шляхам на диску, але з двокрапками замість косих рисок. Таким чином, абсолютне посилання починається з двокрапки:

<a n:href=":Admin:Product:show">odkaz na Admin:Product:show</a>

Щоб дізнатися, чи перебуваємо ми в певному модулі або підмодулі, ми використовуємо функцію isModuleCurrent(moduleName).

<li n:class="isModuleCurrent('Forum:Users') ? active">
	<a n:href="Product:">...</a>
</li>

Маршрутизація

Див. розділ про маршрутизацію.

Складання карти

Визначає правила, за якими ім'я класу виводиться з імені ведучого. Ми записуємо їх у конфігурацію під ключем application › mapping.

Почнемо з прикладу, в якому не використовуються модулі. Ми просто хочемо, щоб класи ведучого мали простір імен App\Presenters. Тобто ми хочемо, щоб ведучий, наприклад, Home відображався на клас App\Presenters\HomePresenter. Цього можна досягти за допомогою такої конфігурації:

application:
	mapping: App\Presenters\*Presenter

Ім'я презентера замінюється зірочкою, і в результаті виходить назва класу. Легко!

Якщо ми розділимо доповідачів на модулі, то для кожного модуля в нас може бути свій маппінг:

application:
	mapping:
		Front: App\Modules\Front\Presenters\*Presenter
		Admin: App\Modules\Admin\Presenters\*Presenter
		Api: App\Api\*Presenter

Тепер презентер Front:Home визначається класом App\Modules\Front\HomePresenter, а презентер Admin:Dashboard ` – App\AdminModule\DashboardPresenter.

Зручніше буде створити загальне правило (зірочка), яке замінить перші два правила і додасть додаткову зірочку тільки для модуля:

application:
	mapping:
		*: App\Modules\*\Presenters\*Presenter
		Api: App\Api\*Presenter

Але що якщо ми використовуємо кілька вкладених модулів і в нас є, наприклад, провідний Admin:User:Edit? У цьому випадку сегмент із зірочкою, що представляє модуль для кожного рівня, буде просто повторюватися, і результатом буде клас App\Modules\Admin\User\Presenters\EditPresenter.

Альтернативною нотацією є використання масиву, що складається з трьох сегментів, замість рядка. Ця нотація еквівалентна попередній:

application:
	mapping:
		*: [App\Modules, *, Presenters\*Presenter]

Значення за замовчуванням – *Module\*Presenter.

версію: 4.0