Модулі
Модулі вносять ясність у додатки Nette, полегшуючи поділ на логічні блоки.
Подібно до організації файлів у папки на жорсткому диску, в Nette ми можемо розділити презентатори, шаблони та інші допоміжні класи на модулі. Як це працює на практиці? Просто додаванням нових підкаталогів до структури. Ось приклад структури з двома модулями, Front і Admin:
app/ ├── UI/ │ ├── Admin/ ← Admin module │ │ ├── @layout.latte │ │ ├── Dashboard/ │ │ │ ├── DashboardPresenter.php │ │ │ └── default.latte │ │ └── ... │ ├── Front/ ← Front module │ │ ├── @layout.latte │ │ ├── Home/ │ │ │ ├── HomePresenter.php │ │ │ └── default.latte │ │ └── ...
Ця структура каталогів відображається в просторах імен класів, тому,
наприклад, DashboardPresenter
знаходиться в просторі імен
App\UI\Admin\Dashboard
:
namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
// ...
}
У програмі ми звертаємось до доповідача Dashboard
у модулі
Admin
, використовуючи двокрапку, як Admin:Dashboard
. Для його дії
default
ми звертаємось до нього як Admin:Dashboard:default
.
Представлена структура не є жорсткою; ви можете повністю налаштувати її відповідно до ваших потреб у конфігурації.
Модулі можуть включати всі інші файли, такі як компоненти і допоміжні
класи, на додаток до презентаторів і шаблонів. Якщо ви обмірковуєте, де
їх розмістити, розгляньте можливість використання папки
Accessory
:
app/ ├── UI/ │ ├── Admin/ │ │ ├── Accessory/ │ │ │ ├── FormFactory.php │ │ │ └── AdminLayout.php │ │ ├── Dashboard/ │ │ └── ...
Вкладені модулі
Модулі можуть мати кілька рівнів вкладеності, подібно до структури каталогів на диску:
app/ ├── UI/ │ ├── Blog/ ← Blog module │ │ ├── Admin/ ← Admin submodule │ │ │ ├── Dashboard/ │ │ │ └── ... │ │ ├── Front/ ← Front submodule │ │ │ ├── @layout.latte │ │ │ ├── Home/ │ │ │ └── ... │ ├── Forum/ ← Forum module │ │ └── ...
Модуль Blog
поділяється на підмодулі Admin
і Front
. Це
також відображається у просторах імен, які потім з'являються як
App\UI\Blog\Admin
і подібним чином. Щоб звернутися до доповідача
Dashboard
у підмодулі Admin
, ми посилаємося на нього як
Blog:Admin:Dashboard
.
Вкладеність може бути настільки глибокою, наскільки це необхідно, що дозволяє створювати підмодулі.
Наприклад, якщо в адмініструванні ви маєте багато доповідачів,
пов'язаних з управлінням замовленнями, таких як OrderDetail
,
OrderEdit
, OrderDispatch
і т.д., ви можете створити модуль Order
,
в якому будуть організовані доповідачі Detail
, Edit
,
Dispatch
та інші.
Створення посилань
Посилання в шаблонах ведучого є відносними щодо поточного модуля.
Таким чином, посилання 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
.
Структури каталогів, згадані раніше на цій сторінці, базуються на наступному відображенні:
application:
mapping: App\UI\*\**Presenter
Як працює мапування? Для кращого розуміння, давайте спочатку уявимо
додаток без модулів. Ми хочемо, щоб класи доповідача потрапляли до
простору імен App\UI
, щоб доповідач Home
відображався у клас
App\UI\HomePresenter
. Цього можна досягти за допомогою такої
конфігурації:
application:
mapping: App\UI\*Presenter
Це відображення працює шляхом заміни зірочки у масці
App\UI\*Presenter
на ім'я доповідача Home
, в результаті чого ми
отримаємо кінцеве ім'я класу App\UI\HomePresenter
. Все просто!
Однак, як ви можете бачити у прикладах у цій та інших главах, ми
розміщуємо класи доповідачів у однойменних підкаталогах, наприклад,
доповідач Home
зіставляється з класом App\UI\Home\HomePresenter
. Це
досягається за допомогою подвоєння зірочки (потрібно Nette Application 3.2):
application:
mapping: App\UI\**Presenter
Тепер перейдемо до зіставлення доповідачів з модулями. Для кожного модуля ми можемо визначити специфічні відображення:
application:
mapping:
Front: App\UI\Front\**Presenter
Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
Згідно з цією конфігурацією, доповідач Front:Home
зіставляється з
класом App\UI\Front\Home\HomePresenter
, а доповідач Api:OAuth
зіставляється
з класом App\Api\OAuthPresenter
.
Оскільки модулі Front
і Admin
мають подібний підхід до
зіставлення і таких модулів, ймовірно, буде більше, можна створити
загальне правило, яке замінить їх. До маски класу буде додано нову
зірочку для модуля:
application:
mapping:
*: App\UI\*\**Presenter
Api: App\Api\*Presenter
Для багаторівневих вкладених модулів, таких як доповідач
Admin:User:Edit
, сегмент зірочки повторюється для кожного рівня, в
результаті чого утворюється клас App\UI\Admin\User\Edit\EditPresenter
.
Альтернативним варіантом запису є використання масиву, що складається з трьох сегментів, замість рядка. Цей запис еквівалентний попередньому:
application:
mapping:
*: [App\UI, *, **Presenter]
Api: [App\Api, '', *Presenter]
Якщо в конфігурації є лише одне правило, загальне, ми можемо написати його коротко:
application:
mapping: App\UI\*\**Presenter