Nette Documentation Preview

syntax
Moduli
******

.[perex]
In Nette, i moduli rappresentano le unità logiche che compongono un'applicazione. Comprendono presentatori, modelli, eventualmente anche componenti e classi di modelli.

Una cartella per i presentatori e una per i modelli non sarebbe sufficiente per i progetti reali. Avere decine di file in una cartella è quantomeno disorganizzato. Come uscirne? Semplicemente dividendoli in sottodirectory su disco e in spazi dei nomi nel codice. E questo è esattamente ciò che fanno i moduli Nette.

Dimentichiamo quindi un'unica cartella per i presentatori e i modelli e creiamo invece dei moduli, ad esempio `Admin` e `Front`.

/--pre
<b>app/</b>
├── <del>Presenters/</del>
├── <b>Modules/</b>              ← directory with modules
│   ├── <b>Admin/</b>            ← module Admin
│   │   ├── <b>Presenters/</b>   ← its presenters
│   │   │   ├── <b>DashboardPresenter.php</b>
│   │   │   └── <b>templates/</b>
│   └── <b>Front/</b>            ← module Front
│       └── <b>Presenters/</b>   ← its presenters
│           └── ...
\--

Questa struttura di cartelle si rifletterà negli spazi dei nomi delle classi, quindi ad esempio `DashboardPresenter` sarà nello spazio dei nomi `App\Modules\Admin\Presenters`:

```php
namespace App\Modules\Admin\Presenters;

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

Il presentatore `Dashboard` all'interno del modulo `Admin` è referenziato all'interno dell'applicazione usando la notazione dei due punti come `Admin:Dashboard`, e la sua azione `default` come `Admin:Dashboard:default`.
E come fa Nette a sapere che `Admin:Dashboard` rappresenta la classe `App\Modules\Admin\Presenters\DashboardPresenter`? Questo è determinato dalla [mappatura |#mapping] nella configurazione.
Pertanto, la struttura data non è rigida e può essere modificata in base alle proprie esigenze.

I moduli possono naturalmente contenere tutti gli altri elementi oltre ai presentatori e ai modelli, come componenti, classi di modelli, ecc.


Moduli annidati .[#toc-nested-modules]
--------------------------------------

I moduli non devono formare solo una struttura piatta, ma si possono anche creare sottomoduli, ad esempio:

/--pre
<b>app/</b>
├── <b>Modules/</b>              ← directory with modules
│   ├── <b>Blog/</b>             ← module Blog
│   │   ├── <b>Admin/</b>        ← submodule Admin
│   │   │   ├── <b>Presenters/</b>
│   │   │   └── ...
│   │   └── <b>Front/</b>        ← submodule Front
│   │       ├── <b>Presenters/</b>
│   │       └── ...
│   ├── <b>Forum/</b>            ← module Forum
│   │   └── ...
\--

Così, il modulo `Blog` è suddiviso nei sottomoduli `Admin` e `Front`. Anche in questo caso, ciò si rifletterà negli spazi dei nomi, che saranno `App\Modules\Blog\Admin\Presenters` e così via. Il presentatore `Dashboard` all'interno del sottomodulo viene chiamato `Blog:Admin:Dashboard`.

L'annidamento può andare in profondità quanto si vuole, quindi si possono creare dei sottomoduli.


Creazione di collegamenti .[#toc-creating-links]
------------------------------------------------

I collegamenti nei modelli di presentatore sono relativi al modulo corrente. Pertanto, il collegamento `Foo:default` porta al presentatore `Foo` nello stesso modulo del presentatore corrente. Se il modulo corrente è `Front`, ad esempio, il collegamento si presenta in questo modo:

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

Un collegamento è relativo anche se include il nome di un modulo, che viene considerato un sottomodulo:

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

I collegamenti assoluti sono scritti in modo analogo ai percorsi assoluti su disco, ma con i due punti al posto degli slash. Pertanto, un collegamento assoluto inizia con i due punti:

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

Per scoprire se ci troviamo in un certo modulo o in un suo sottomodulo possiamo usare la funzione `isModuleCurrent(moduleName)`.

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


Instradamento .[#toc-routing]
-----------------------------

Vedere il [capitolo sull'instradamento |routing#Modules].


Mappatura .[#toc-mapping]
-------------------------

Definisce le regole con cui il nome della classe viene derivato dal nome del presentatore. Vengono scritte nella [configurazione |configuration] sotto la chiave `application › mapping`.

Cominciamo con un esempio che non usa moduli. Vogliamo solo che le classi del presentatore abbiano lo spazio dei nomi `App\Presenters`. Ciò significa che un presentatore come `Home` deve mappare alla classe `App\Presenters\HomePresenter`. Questo si può ottenere con la seguente configurazione:

```neon
application:
	mapping: App\Presenters\*Presenter
```

Il nome del presentatore viene sostituito con l'asterisco nella maschera della classe e il risultato è il nome della classe. Facile!

Se dividiamo i presentatori in moduli, possiamo avere la nostra mappatura per ogni modulo:

```neon
application:
	mapping:
		Front: App\Modules\Front\Presenters\*Presenter
		Admin: App\Modules\Admin\Presenters\*Presenter
		Api: App\Api\*Presenter
```

Ora il presentatore `Front:Home` mappa alla classe `App\Modules\Front\Presenters\HomePresenter` e il presentatore `Admin:Dashboard` alla classe `App\Modules\Admin\Presenters\DashboardPresenter`.

È più pratico creare una regola generale (asterisco) per sostituire le prime due. L'asterisco in più sarà aggiunto alla maschera di classe solo per il modulo:

```neon
application:
	mapping:
		*: App\Modules\*\Presenters\*Presenter
		Api: App\Api\*Presenter
```

Ma cosa succede se utilizziamo moduli annidati e abbiamo un presentatore `Admin:User:Edit`? In questo caso, il segmento con l'asterisco che rappresenta il modulo per ogni livello viene semplicemente ripetuto e il risultato è la classe `App\Modules\Admin\User\Presenters\EditPresenter`.

Una notazione alternativa consiste nell'utilizzare un array composto da tre segmenti invece di una stringa. Questa notazione è equivalente alla precedente:

```neon
application:
	mapping:
		*: [App\Modules, *, Presenters\*Presenter]
```

Il valore predefinito è `*Module\*Presenter`.

Moduli

In Nette, i moduli rappresentano le unità logiche che compongono un'applicazione. Comprendono presentatori, modelli, eventualmente anche componenti e classi di modelli.

Una cartella per i presentatori e una per i modelli non sarebbe sufficiente per i progetti reali. Avere decine di file in una cartella è quantomeno disorganizzato. Come uscirne? Semplicemente dividendoli in sottodirectory su disco e in spazi dei nomi nel codice. E questo è esattamente ciò che fanno i moduli Nette.

Dimentichiamo quindi un'unica cartella per i presentatori e i modelli e creiamo invece dei moduli, ad esempio Admin e Front.

app/
├── Presenters/
├── Modules/              ← directory with modules
│   ├── Admin/            ← module Admin
│   │   ├── Presenters/   ← its presenters
│   │   │   ├── DashboardPresenter.php
│   │   │   └── templates/
│   └── Front/            ← module Front
│       └── Presenters/   ← its presenters
│           └── ...

Questa struttura di cartelle si rifletterà negli spazi dei nomi delle classi, quindi ad esempio DashboardPresenter sarà nello spazio dei nomi App\Modules\Admin\Presenters:

namespace App\Modules\Admin\Presenters;

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

Il presentatore Dashboard all'interno del modulo Admin è referenziato all'interno dell'applicazione usando la notazione dei due punti come Admin:Dashboard, e la sua azione default come Admin:Dashboard:default. E come fa Nette a sapere che Admin:Dashboard rappresenta la classe App\Modules\Admin\Presenters\DashboardPresenter? Questo è determinato dalla mappatura nella configurazione. Pertanto, la struttura data non è rigida e può essere modificata in base alle proprie esigenze.

I moduli possono naturalmente contenere tutti gli altri elementi oltre ai presentatori e ai modelli, come componenti, classi di modelli, ecc.

Moduli annidati

I moduli non devono formare solo una struttura piatta, ma si possono anche creare sottomoduli, ad esempio:

app/
├── Modules/              ← directory with modules
│   ├── Blog/             ← module Blog
│   │   ├── Admin/        ← submodule Admin
│   │   │   ├── Presenters/
│   │   │   └── ...
│   │   └── Front/        ← submodule Front
│   │       ├── Presenters/
│   │       └── ...
│   ├── Forum/            ← module Forum
│   │   └── ...

Così, il modulo Blog è suddiviso nei sottomoduli Admin e Front. Anche in questo caso, ciò si rifletterà negli spazi dei nomi, che saranno App\Modules\Blog\Admin\Presenters e così via. Il presentatore Dashboard all'interno del sottomodulo viene chiamato Blog:Admin:Dashboard.

L'annidamento può andare in profondità quanto si vuole, quindi si possono creare dei sottomoduli.

I collegamenti nei modelli di presentatore sono relativi al modulo corrente. Pertanto, il collegamento Foo:default porta al presentatore Foo nello stesso modulo del presentatore corrente. Se il modulo corrente è Front, ad esempio, il collegamento si presenta in questo modo:

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

Un collegamento è relativo anche se include il nome di un modulo, che viene considerato un sottomodulo:

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

I collegamenti assoluti sono scritti in modo analogo ai percorsi assoluti su disco, ma con i due punti al posto degli slash. Pertanto, un collegamento assoluto inizia con i due punti:

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

Per scoprire se ci troviamo in un certo modulo o in un suo sottomodulo possiamo usare la funzione isModuleCurrent(moduleName).

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

Instradamento

Vedere il capitolo sull'instradamento.

Mappatura

Definisce le regole con cui il nome della classe viene derivato dal nome del presentatore. Vengono scritte nella configurazione sotto la chiave application › mapping.

Cominciamo con un esempio che non usa moduli. Vogliamo solo che le classi del presentatore abbiano lo spazio dei nomi App\Presenters. Ciò significa che un presentatore come Home deve mappare alla classe App\Presenters\HomePresenter. Questo si può ottenere con la seguente configurazione:

application:
	mapping: App\Presenters\*Presenter

Il nome del presentatore viene sostituito con l'asterisco nella maschera della classe e il risultato è il nome della classe. Facile!

Se dividiamo i presentatori in moduli, possiamo avere la nostra mappatura per ogni modulo:

application:
	mapping:
		Front: App\Modules\Front\Presenters\*Presenter
		Admin: App\Modules\Admin\Presenters\*Presenter
		Api: App\Api\*Presenter

Ora il presentatore Front:Home mappa alla classe App\Modules\Front\Presenters\HomePresenter e il presentatore Admin:Dashboard alla classe App\Modules\Admin\Presenters\DashboardPresenter.

È più pratico creare una regola generale (asterisco) per sostituire le prime due. L'asterisco in più sarà aggiunto alla maschera di classe solo per il modulo:

application:
	mapping:
		*: App\Modules\*\Presenters\*Presenter
		Api: App\Api\*Presenter

Ma cosa succede se utilizziamo moduli annidati e abbiamo un presentatore Admin:User:Edit? In questo caso, il segmento con l'asterisco che rappresenta il modulo per ogni livello viene semplicemente ripetuto e il risultato è la classe App\Modules\Admin\User\Presenters\EditPresenter.

Una notazione alternativa consiste nell'utilizzare un array composto da tre segmenti invece di una stringa. Questa notazione è equivalente alla precedente:

application:
	mapping:
		*: [App\Modules, *, Presenters\*Presenter]

Il valore predefinito è *Module\*Presenter.