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.

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.

različica: 4.0