Модули
В 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
.