Moduli
V Nette moduli predstavljajo logične enote, ki sestavljajo aplikacijo. Vključujejo predstavnike, predloge, lahko tudi komponente in razrede modelov.
En imenik za predstavnike in en imenik za predloge za prave projekte ne bi bil dovolj. Če je v eni mapi na desetine datotek, je to vsaj neorganizirano. Kako to odpraviti? Preprosto jih razdelimo v podimenike na disku in v imenske prostore v kodi. In točno to naredijo moduli Nette.
Pozabimo torej na eno mapo za predstavnike in predloge in namesto tega ustvarimo module, na primer Admin
in
Front
.
app/ ├──Presenters/├── Modules/ ← directory with modules │ ├── Admin/ ← module Admin │ │ ├── Presenters/ ← its presenters │ │ │ ├── DashboardPresenter.php │ │ │ └── templates/ │ └── Front/ ← module Front │ └── Presenters/ ← its presenters │ └── ...
Ta struktura imenikov se bo odražala v imenskih prostorih razredov, tako da bo na primer DashboardPresenter
v imenskem prostoru App\Modules\Admin\Presenters
:
namespace App\Modules\Admin\Presenters;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
// ...
}
Na predvajalnik Dashboard
znotraj modula Admin
se v aplikaciji sklicujemo z uporabo zapisa
v dvopičju kot na Admin:Dashboard
, na njegovo akcijo default
pa kot na
Admin:Dashboard:default
. In kako Nette pravilno ve, da Admin:Dashboard
predstavlja razred
App\Modules\Admin\Presenters\DashboardPresenter
? To je določeno s preslikavo
v konfiguraciji. Podana struktura torej ni trdno določena in jo lahko spreminjate glede na svoje potrebe.
Moduli seveda lahko poleg predstavnikov in predlog vsebujejo tudi vse druge elemente, kot so komponente, razredi modelov itd.
Vgnezdeni moduli
Ni nujno, da moduli tvorijo le ravno strukturo, ustvarite lahko tudi podmodule, na primer:
app/ ├── Modules/ ← directory with modules │ ├── Blog/ ← module Blog │ │ ├── Admin/ ← submodule Admin │ │ │ ├── Presenters/ │ │ │ └── ... │ │ └── Front/ ← submodule Front │ │ ├── Presenters/ │ │ └── ... │ ├── Forum/ ← module Forum │ │ └── ...
Tako je modul Blog
razdeljen na podmodula Admin
in Front
. Tudi to se bo odražalo
v imenskih prostorih, ki bodo App\Modules\Blog\Admin\Presenters
itd. Predstavnik Dashboard
znotraj
podmodula se imenuje Blog:Admin:Dashboard
.
Gnezdenje je lahko tako globoko, kot želite, zato lahko ustvarite podmodule.
Ustvarjanje povezav
Povezave v predlogah za predstavitev so relativne glede na trenutni modul. Tako povezava Foo:default
vodi do
predstavitvene predloge Foo
v istem modulu kot trenutna predstavitvena predloga. Če je trenutni modul na primer
Front
, potem povezava poteka takole:
<a n:href="Product:show">link to Front:Product:show</a>
Povezava je relativna tudi, če vključuje ime modula, ki se potem šteje za podmodul:
<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>
Absolutne povezave se zapišejo podobno kot absolutne poti na disku, vendar s podpičjem namesto šumnikov. Tako se absolutna povezava začne z dvopičjem:
<a n:href=":Admin:Product:show">link to Admin:Product:show</a>
Če želimo ugotoviti, ali smo v določenem modulu ali njegovem podmodulu, lahko uporabimo funkcijo
isModuleCurrent(moduleName)
.
<li n:class="isModuleCurrent('MyEshop:Users') ? active">
<a n:href="Product:">...</a>
</li>
Usmerjanje
Glejte poglavje o usmerjanju.
Kartiranje
Določa pravila, po katerih se ime razreda izpelje iz imena predstavnika. Zapišemo jih v konfiguracijo pod ključ application › mapping
.
Začnimo z vzorcem, ki ne uporablja modulov. Želeli bomo le, da imajo razredi predstavnikov imenski prostor
App\Presenters
. To pomeni, da mora biti predstavnik, kot je Home
, preslikan v razred
App\Presenters\HomePresenter
. To lahko dosežemo z naslednjo konfiguracijo:
application:
mapping:
*: App\Presenters\*Presenter
V maski razreda se ime predvajalnika nadomesti z zvezdico, rezultat pa je ime razreda. Enostavno!
Če voditelje razdelimo na module, lahko za vsak modul pripravimo lastno preslikavo:
application:
mapping:
Front: App\Modules\Front\Presenters\*Presenter
Admin: App\Modules\Admin\Presenters\*Presenter
Api: App\Api\*Presenter
Sedaj je predstavnik Front:Home
preslikan v razred App\Modules\Front\Presenters\HomePresenter
,
predstavnik Admin:Dashboard
pa v razred App\Modules\Admin\Presenters\DashboardPresenter
.
Bolj praktično je ustvariti splošno (zvezdno) pravilo, ki bo nadomestilo prvi dve. Dodatna zvezdica bo dodana maski razreda samo za ta modul:
application:
mapping:
*: App\Modules\*\Presenters\*Presenter
Api: App\Api\*Presenter
Kaj pa, če uporabljamo vgnezdene module in imamo predvajalnik Admin:User:Edit
? V tem primeru se segment
z zvezdico, ki predstavlja modul za vsako raven, preprosto ponovi in rezultat je razred
App\Modules\Admin\User\Presenters\EditPresenter
.
Alternativni zapis je, da namesto niza uporabimo polje, sestavljeno iz treh segmentov. Ta zapis je enakovreden prejšnjemu:
application:
mapping:
*: [App\Modules, *, Presenters\*Presenter]
Privzeta vrednost je *: *Module\*Presenter
.