Moduly
Moduly vnášejí do Nette aplikací přehlednost díky snadnému členění do logických celků.
Podobně jako na pevném disku organizujeme soubory do jednotlivých složek, tak i v Nette můžeme presentery, šablony a další pomocné třídy rozdělovat do modulů. Jak to funguje v praxi? Jednoduše začleníme do struktury nové podadresáře. Příklad takové struktury se dvěma moduly Front a Admin:
app/ ├── UI/ │ ├── Admin/ ← modul Admin │ │ ├── @layout.latte │ │ ├── Dashboard/ │ │ │ ├── DashboardPresenter.php │ │ │ └── default.latte │ │ └── ... │ ├── Front/ ← modul Front │ │ ├── @layout.latte │ │ ├── Home/ │ │ │ ├── HomePresenter.php │ │ │ └── default.latte │ │ └── ...
Tato adresářová struktura se odráží ve jmenných prostorech tříd, takže například DashboardPresenter
se
nachází ve jmenném prostoru App\UI\Admin\Dashboard
:
namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
// ...
}
Na presenter Dashboard
uvnitř modulu Admin
odkazujeme v aplikaci pomocí dvojtečkové notace jako
na Admin:Dashboard
. Na jeho akci default
potom jako na Admin:Dashboard:default
.
Představená struktura není pevná; můžete si ji zcela přizpůsobit dle svých potřeb v konfiguraci.
Moduly mohou kromě presenterů a šablon samozřejmě zahrnovat všechny ostatní soubory, jako jsou například komponenty a
pomocné třídy. Pokud uvažujete, kam je zařadit, zvažte využití složky Accessory
:
app/ ├── UI/ │ ├── Admin/ │ │ ├── Accessory/ │ │ │ ├── FormFactory.php │ │ │ └── AdminLayout.php │ │ ├── Dashboard/ │ │ └── ...
Vnořené moduly
Moduly mohou mít více úrovní zanoření, podobně jako adresářová struktura na disku:
app/ ├── UI/ │ ├── Blog/ ← modul Blog │ │ ├── Admin/ ← submodul Admin │ │ │ ├── Dashboard/ │ │ │ └── ... │ │ ├── Front/ ← submodul Front │ │ │ ├── @layout.latte │ │ │ ├── Home/ │ │ │ └── ... │ ├── Forum/ ← modul Forum │ │ └── ...
Modul Blog
je rozdělen na submoduly Admin
a Front
. To se projeví i ve jmenných
prostorech, které pak budou vypadat jako App\UI\Blog\Admin
a podobně. Na presenter Dashboard
v rámci
submodulu odkazujeme jako na Blog:Admin:Dashboard
.
Zanoření může být libovolně hluboké, což umožňuje vytvářet sub-submoduly.
Pokud například v administraci máte mnoho presenterů týkajících se správy objednávek, jako jsou
OrderDetail
, OrderEdit
, OrderDispatch
atd., můžete pro lepší organizovanost vytvořit
modul Order
, ve kterém budou presentery Detail
, Edit
, Dispatch
a další.
Vytváření odkazů
Odkazy v šablonách presenterů jsou relativní vůči aktuálnímu modulu. Tedy odkaz Foo:default
vede na
presenter Foo
v tomtéž modulu, v jakém je aktuální presenter. Pokud je aktuální modul například
Front
, pak odkaz vede takto:
<a n:href="Product:show">odkaz na Front:Product:show</a>
Odkaz je relativní i pokud je jeho součástí název modulu, ten se pak považuje za submodul:
<a n:href="Shop:Product:show">odkaz na Front:Shop:Product:show</a>
Absolutní odkazy zapisujeme analogicky k absolutním cestám na disku, jen místo lomítek jsou dvojtečky. Tedy absolutní odkaz začíná dvojtečkou:
<a n:href=":Admin:Product:show">odkaz na Admin:Product:show</a>
Pro zjištění, zda jsme v určitém modulu nebo jeho submodulu, použijeme funkci
isModuleCurrent(moduleName)
.
<li n:class="isModuleCurrent('Forum:Users') ? active">
<a n:href="Product:">...</a>
</li>
Routování
Viz kapitola o routování.
Mapování
Mapování definuje pravidla pro odvozování názvu třídy z názvu presenteru. Specifikujeme je v konfiguraci pod klíčem application › mapping
.
Adresářové struktury uváděné výše na této stránce vycházejí z tohoto mapování:
application:
mapping: App\UI\*\**Presenter
Jak mapování funguje? Pro lepší pochopení si nejprve představme aplikaci bez modulů. Chceme, aby třídy presenterů
spadaly do jmenného prostoru App\UI
, aby se presenter Home
mapoval na třídu
App\UI\HomePresenter
. Což dosáhneme touto konfigurací:
application:
mapping: App\UI\*Presenter
Mapování funguje tak, že název presenteru Home
nahradí hvězdičku v masce App\UI\*Presenter
,
čímž získáme výsledný název třídy App\UI\HomePresenter
. Jednoduché!
Jak ale vidíte v ukázkách v této a dalších kapitolách, třídy presenterů umisťujeme do eponymních podadresářů,
například presenter Home
se mapuje na třídu App\UI\Home\HomePresenter
. Toho dosáhneme zdvojením
dvojtečky (vyžaduje Nette Application 3.2):
application:
mapping: App\UI\**Presenter
Nyní přistoupíme k mapování presenterů do modulů. Pro každý modul můžeme definovat specifické mapování:
application:
mapping:
Front: App\UI\Front\**Presenter
Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
Podle této konfigurace se presenter Front:Home
mapuje na třídu App\UI\Front\Home\HomePresenter
,
zatímco presenter Api:OAuth
na třídu App\Api\OAuthPresenter
.
Protože moduly Front
i Admin
mají podobný způsob mapování a takových modulů bude nejspíš
více, je možné vytvořit obecné pravidlo, které je nahradí. Do masky třídy tak přibude nová hvězdička pro modul:
application:
mapping:
*: App\UI\*\**Presenter
Api: App\Api\*Presenter
Pro vícenásobně zanořené moduly, jako je například presenter Admin:User:Edit
, se segment s hvězdičkou
opakuje pro každou úroveň a výsledkem je třída App\UI\Admin\User\Edit\EditPresenter
.
Alternativním zápisem je místo řetězce použít pole skládající se ze tří segmentů. Tento zápis je ekvivaletní s předchozím:
application:
mapping:
*: [App\UI, *, **Presenter]
Api: [App\Api, '', *Presenter]
Pokud bychom měli v konfiguraci jen jediné pravidlo, ono obecné, můžeme zkráceně zapsat:
application:
mapping: App\UI\*\**Presenter