Nette Documentation Preview

syntax
Moduli
******

.[perex]
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`.

/--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
│           └── ...
\--

Ta struktura imenikov se bo odražala v imenskih prostorih razredov, tako da bo na primer `DashboardPresenter` v imenskem prostoru `App\Modules\Admin\Presenters`:

```php
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 |#mapping] 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 .[#toc-nested-modules]
---------------------------------------

Ni nujno, da moduli tvorijo le ravno strukturo, ustvarite lahko tudi podmodule, na primer:

/--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
│   │   └── ...
\--

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.


Ustvarjanje povezav .[#toc-creating-links]
------------------------------------------

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:

```latte
<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:

```latte
<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:

```latte
<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)`.

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


Usmerjanje .[#toc-routing]
--------------------------

Glejte [poglavje o usmerjanju |routing#Modules].


Kartiranje .[#toc-mapping]
--------------------------

Določa pravila, po katerih se ime razreda izpelje iz imena predstavnika. Zapišemo jih v [konfiguracijo |configuration] 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:

```neon
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:

```neon
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:

```neon
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:

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

Privzeta vrednost je `*: *Module\*Presenter`.

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.