Modulok

A modulok a Nette-alkalmazások áttekinthetőségét segítik elő azáltal, hogy megkönnyítik a logikai egységekre való egyszerű felosztást.

Hasonlóan a fájlok mappákba rendezéséhez a merevlemezen, a Nette-ben modulokba oszthatjuk a prezentereket, sablonokat és más segédosztályokat. Hogyan működik ez a gyakorlatban? Egyszerűen úgy, hogy új alkönyvtárakat építünk be a struktúrába. Íme egy példa egy struktúrára két modullal, a Front és az Admin modulokkal:

app/
├── UI/
│   ├── Admin/            ← Admin module
│   │   ├── @layout.latte
│   │   ├── Dashboard/
│   │   │   ├── DashboardPresenter.php
│   │   │   └── default.latte
│   │   └── ...
│   ├── Front/            ← Front module
│   │   ├── @layout.latte
│   │   ├── Home/
│   │   │   ├── HomePresenter.php
│   │   │   └── default.latte
│   │   └── ...

Ez a könyvtárszerkezet tükröződik az osztályok névterében, így például a DashboardPresenter a App\UI\Admin\Dashboard névtérben található:

namespace App\UI\Admin\Dashboard;

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

Az alkalmazásban a Dashboard bemutatóra a Admin modulon belül a Admin:Dashboard kettőspont jelöléssel hivatkozunk a . A default műveletére Admin:Dashboard:default néven hivatkozunk.

A bemutatott struktúra nem merev; a konfigurációban teljes mértékben az igényeihez igazíthatja.

A modulok a prezentereken és sablonokon kívül minden más fájlt, például komponenseket és segédosztályokat is tartalmazhatnak. Ha mérlegeli, hogy hol helyezze el ezeket, fontolja meg a Accessory mappa használatát:

app/
├── UI/
│   ├── Admin/
│   │   ├── Accessory/
│   │   │   ├── FormFactory.php
│   │   │   └── AdminLayout.php
│   │   ├── Dashboard/
│   │   └── ...

Beágyazott modulok

A modulok több szinten is egymásba ágyazhatók, hasonlóan a lemezen lévő könyvtárstruktúrához:

app/
├── UI/
│   ├── Blog/             ← Blog module
│   │   ├── Admin/        ← Admin submodule
│   │   │   ├── Dashboard/
│   │   │   └── ...
│   │   ├── Front/        ← Front submodule
│   │   │   ├── @layout.latte
│   │   │   ├── Home/
│   │   │   └── ...
│   ├── Forum/            ← Forum module
│   │   └── ...

A Blog modul Admin és Front almodulokra oszlik. Ez tükröződik a névterekben is, amelyek aztán App\UI\Blog\Admin és hasonló módon jelennek meg. A Dashboard bemutatóra a Admin almodulon belül Blog:Admin:Dashboard néven hivatkozunk.

A beágyazás olyan mély lehet, amilyen mélyre csak szükséges, lehetővé téve al-almodulok létrehozását.

Például, ha az adminisztrációban sok, a rendeléskezeléshez kapcsolódó prezenter van, mint például OrderDetail, OrderEdit, OrderDispatch, stb., létrehozhat egy Order modult, amelyben a Detail, Edit, Dispatch, stb. típusú prezentereket szervezi.

A bemutatósablonokban lévő hivatkozások az aktuális modulhoz viszonyítva vannak. Így a Foo:default hivatkozás a Foo bemutatóhoz vezet, amely ugyanabban a modulban található, mint az aktuális bemutató. Ha az aktuális modul például a Front, akkor a link így néz ki:

<a n:href="Product:show">link to Front:Product:show</a>

A hivatkozás akkor is relatív, ha egy modul nevét tartalmazza, amely ilyenkor almodulnak minősül:

<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>

Az abszolút hivatkozások a lemezen lévő abszolút elérési utakhoz hasonlóan íródnak, de a kettőspontok helyett kettőspontokkal. Az abszolút link tehát kettősponttal kezdődik:

<a n:href=":Admin:Product:show">link to Admin:Product:show</a>

Hogy megtudjuk, hogy egy adott modulban vagy annak almoduljában vagyunk-e, használhatjuk a isModuleCurrent(moduleName) függvényt.

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

Útválasztás

Lásd az útválasztásról szóló fejezetet.

A feltérképezése

A leképezés határozza meg az osztálynévnek a bemutató nevéből való származtatásának szabályait. Ezek a szabályok a konfigurációban a application › mapping kulcs alatt vannak megadva.

Az ezen az oldalon korábban említett könyvtárszerkezetek a következő leképezésen alapulnak:

application:
	mapping: App\UI\*\**Presenter

Hogyan működik a térképezés? A jobb megértés érdekében először képzeljünk el egy modulok nélküli alkalmazást. Szeretnénk, ha a prezenter osztályok a App\UI névtérbe tartoznának, így a Home prezenter a App\UI\HomePresenter osztályhoz tartozik. Ezt a következő konfigurációval érhetjük el:

application:
	mapping: App\UI\*Presenter

Ez a leképezés úgy működik, hogy a App\UI\*Presenter maszkban a csillagot a Home prezenter névvel helyettesítjük, így kapjuk a App\UI\HomePresenter végső osztálynevet. Egyszerű!

Azonban, ahogyan azt az ebben és más fejezetekben található példákban láthatjuk, a prezenter osztályokat névadó alkönyvtárakba helyezzük, például a Home prezenter a App\UI\Home\HomePresenter osztályra van leképezve. Ezt a csillag megduplázásával érjük el (Nette Application 3.2 szükséges):

application:
	mapping: App\UI\**Presenter

Most pedig térjünk rá az előadók modulokba való leképezésére. Minden egyes modulhoz sajátos hozzárendeléseket határozhatunk meg:

application:
	mapping:
		Front: App\UI\Front\**Presenter
		Admin: App\UI\Admin\**Presenter
		Api: App\Api\*Presenter

E konfiguráció szerint a Front:Home bemutató a App\UI\Front\Home\HomePresenter osztályhoz, míg a Api:OAuth bemutató a App\Api\OAuthPresenter osztályhoz tartozik.

Mivel a Front és a Admin modulok hasonló leképezési megközelítéssel rendelkeznek, és valószínűleg több ilyen modul is létezik, létrehozható egy általános szabály, amely ezeket helyettesíti. Az osztálymaszkhoz egy új csillagot adunk a modulhoz:

application:
	mapping:
		*: App\UI\*\**Presenter
		Api: App\Api\*Presenter

A többszintű, egymásba ágyazott modulok esetében, mint például a Admin:User:Edit bemutató, a csillagszegmens minden szinten megismétlődik, így a App\UI\Admin\User\Edit\EditPresenter osztály lesz az eredmény.

Egy alternatív jelölés a karakterlánc helyett egy három szegmensből álló tömb használata. Ez a jelölés egyenértékű az előzővel:

application:
	mapping:
		*: [App\UI, *, **Presenter]
		Api: [App\Api, '', *Presenter]

Ha csak egy szabály van a konfigurációban, az általános szabály, akkor röviden leírhatjuk:

application:
	mapping: App\UI\*\**Presenter