Module
În Nette, modulele reprezintă unitățile logice care alcătuiesc o aplicație. Acestea includ prezentatori, șabloane, eventual și componente și clase de model.
Un singur director pentru prezentatori și unul pentru șabloane nu ar fi suficient pentru proiectele reale. A avea zeci de fișiere într-un singur dosar este cel puțin neorganizat. Cum se poate ieși din asta? Pur și simplu le împărțim în subdirectoare pe disc și în spații de nume în cod. Și asta este exact ceea ce fac modulele Nette.
Așadar, să uităm de un singur dosar pentru prezentatori și șabloane și să creăm în schimb module, de exemplu
Admin
și Front
.
app/ ├──Presenters/├── Modules/ ← directory with modules │ ├── Admin/ ← module Admin │ │ ├── Presenters/ ← its presenters │ │ │ ├── DashboardPresenter.php │ │ │ └── templates/ │ └── Front/ ← module Front │ └── Presenters/ ← its presenters │ └── ...
Această structură de directoare va fi reflectată de spațiile de nume ale claselor, astfel încât, de exemplu,
DashboardPresenter
va fi în spațiul de nume App\Modules\Admin\Presenters
:
namespace App\Modules\Admin\Presenters;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
// ...
}
Prezentatorul Dashboard
din cadrul modulului Admin
este referit în cadrul aplicației folosind
notația de două puncte ca Admin:Dashboard
, iar acțiunea default
ca
Admin:Dashboard:default
. Și de unde știe Nette proper că Admin:Dashboard
reprezintă clasa
App\Modules\Admin\Presenters\DashboardPresenter
? Acest lucru este determinat de cartografierea din configurație. Așadar, structura dată nu este prestabilită și o puteți modifica
în funcție de nevoile dumneavoastră.
Modulele pot conține, bineînțeles, toate celelalte elemente în afară de prezentatori și șabloane, cum ar fi componente, clase de modele etc.
Module imbricate
Modulele nu trebuie să formeze doar o structură plată, ci puteți crea și submodule, de exemplu:
app/ ├── Modules/ ← directory with modules │ ├── Blog/ ← module Blog │ │ ├── Admin/ ← submodule Admin │ │ │ ├── Presenters/ │ │ │ └── ... │ │ └── Front/ ← submodule Front │ │ ├── Presenters/ │ │ └── ... │ ├── Forum/ ← module Forum │ │ └── ...
Astfel, modulul Blog
este împărțit în submodulele Admin
și Front
. Din nou, acest
lucru se va reflecta în spațiile de nume, care vor fi App\Modules\Blog\Admin\Presenters
etc. Prezentatorul
Dashboard
din interiorul submodulului este denumit Blog:Admin:Dashboard
.
Anveloparea poate merge cât de adânc doriți, astfel încât pot fi create sub-submodule.
Crearea de legături
Legăturile din șabloanele de prezentator sunt relative la modulul curent. Astfel, legătura Foo:default
duce la
prezentatorul Foo
din același modul ca și prezentatorul curent. Dacă modulul curent este Front
, de
exemplu, atunci legătura se prezintă astfel:
<a n:href="Product:show">link to Front:Product:show</a>
O legătură este relativă chiar dacă include numele unui modul, care este considerat atunci un submodul:
<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>
Legăturile absolute sunt scrise în mod analog cu căile absolute de acces de pe disc, dar cu două puncte în loc de bară oblică. Astfel, o legătură absolută începe cu două puncte:
<a n:href=":Admin:Product:show">link to Admin:Product:show</a>
Pentru a afla dacă ne aflăm într-un anumit modul sau într-un submodul al acestuia, putem utiliza funcția
isModuleCurrent(moduleName)
.
<li n:class="isModuleCurrent('MyEshop:Users') ? active">
<a n:href="Product:">...</a>
</li>
Rutarea
A se vedea capitolul privind rutarea.
Cartografiere
Definește regulile prin care numele clasei este derivat din numele prezentatorului. Le scriem în configurație sub cheia application › mapping
.
Să începem cu un exemplu care nu folosește module. Vom dori doar ca clasele de prezentator să aibă spațiul de nume
App\Presenters
. Aceasta înseamnă că un prezentator precum Home
ar trebui să se mapeze la clasa
App\Presenters\HomePresenter
. Acest lucru poate fi realizat prin următoarea configurație:
application:
mapping:
*: App\Presenters\*Presenter
Numele prezentatorului este înlocuit cu un asterisc în masca clasei, iar rezultatul este numele clasei. Ușor!
Dacă împărțim prezentatorii în module, putem avea propria mapare pentru fiecare modul:
application:
mapping:
Front: App\Modules\Front\Presenters\*Presenter
Admin: App\Modules\Admin\Presenters\*Presenter
Api: App\Api\*Presenter
Acum, prezentatorul Front:Home
se referă la clasa App\Modules\Front\Presenters\HomePresenter
și
prezentatorul Admin:Dashboard
la clasa App\Modules\Admin\Presenters\DashboardPresenter
.
Este mai practic să creăm o regulă generală (stea) care să le înlocuiască pe primele două. Asteriscul suplimentar va fi adăugat la masca clasei doar pentru modul:
application:
mapping:
*: App\Modules\*\Presenters\*Presenter
Api: App\Api\*Presenter
Dar ce se întâmplă dacă folosim module imbricate și avem un prezentator Admin:User:Edit
? În acest caz,
segmentul cu un asterisc care reprezintă modulul pentru fiecare nivel se repetă pur și simplu, iar rezultatul este clasa
App\Modules\Admin\User\Presenters\EditPresenter
.
O notație alternativă este utilizarea unui array format din trei segmente în loc de un șir de caractere. Această notație este echivalentă cu cea anterioară:
application:
mapping:
*: [App\Modules, *, Presenters\*Presenter]
Valoarea implicită este *: *Module\*Presenter
.