Skip to content

Commit

Permalink
dirname2
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Apr 18, 2024
1 parent 1dfe4e9 commit 37af13f
Showing 1 changed file with 68 additions and 39 deletions.
107 changes: 68 additions & 39 deletions application/cs/modules.texy
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,31 @@ Moduly
******

.[perex]
Moduly představují v Nette logické celky, ze kterých se aplikace skládá. Jejich součástí jsou presentery, šablony, případně i komponenty a modelové třídy.
Moduly vnášejí do Nette aplikací přehlednost díky snadnému členění do logických celků.

S jednou složkou pro presentery a jednou pro šablony bychom si u reálných projektů nevystačili. Mít v jedné složce desítky souborů je minimálně nepřehledné. Jak z toho ven? Jednoduše je na disku rozdělíme do podadresářů a v kódu do jmenných prostorů. A přesně to jsou v Nette moduly.

Zapomeňme tedy na jednu složku pro presentery a šablony a místo toho vytvoříme moduly, například `Admin` a `Front`.
Podobně jako si na disku třídíme soubory do jednotlivých adresářů, tak i v Nette si presentery, šablony a další pomocné třídy můžeme zařazovat do modulů. Jak to vypadá v praxi? Jednoduše uspořádáme strukturu do nových podadresářů. Příklad takové struktuy se dvěma moduly `Front` a `Admin`:

/--pre
<b>app/</b>
├── <del>Presenters/</del>
├── <b>Modules/</b> ← adresář s moduly
app/
├── UI/
│ ├── <b>Admin/</b> ← modul Admin
│ │ ├── <b>Presenters/</b> ← jeho presentery
│ │ │ ├── <b>DashboardPresenter.php</b>
│ │ │ └── <b>templates/</b>
│ └── <b>Front/</b> ← modul Front
│ └── <b>Presenters/</b> ← jeho presentery
│ └── ...
│ │ ├── @layout.latte
│ │ ├── Dashboard/
│ │ │ ├── DashboardPresenter.php
│ │ │ └── default.latte
│ │ └── ...
│ ├── <b>Front/</b> ← modul Front
│ │ ├── @layout.latte
│ │ ├── Home/
│ │ │ ├── HomePresenter.php
│ │ │ └── default.latte
│ │ └── ...
\--

Tuto adresářovou strukturu budou reflektovat jmenné prostory tříd, takže třeba `DashboardPresenter` bude v prostoru `App\Modules\Admin\Presenters`:
Tuto adresářovou strukturu budou reflektovat jmenné prostory tříd, takže třeba `DashboardPresenter` bude v prostoru `App\UI\Admin\...`:

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

class DashboardPresenter extends Nette\Application\UI\Presenter
{
Expand All @@ -33,35 +35,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
```

Na presenter `Dashboard` uvnitř modulu `Admin` se v rámci aplikace odkazujeme pomocí dvojtečkové notace jako na `Admin:Dashboard`, na jeho akci `default` potom jako na `Admin:Dashboard:default`.
A jak Nette vlastní ví, že `Admin:Dashboard` představuje třídu `App\Modules\Admin\Presenters\DashboardPresenter`? To mu řekneme pomocí [#mapování] v konfiguraci.
Tedy uvedená struktura není pevná a můžete si ji upravit podle potřeb.

Moduly mohou kromě presenterů a šablon samozřejmě obsahovat všechny další součásti, jako jsou třeba komponenty, modelové třídy, atd.
Uvedená struktura není pevná, naoapk si ji v konfiguraci můžete zcela [přizpůsobit dle potřeby#mapování] v konfiguraci. .[tip]

Moduly mohou kromě presenterů a šablon samozřejmě obsahovat všechny další součásti, jako jsou třeba komponenty a různé pomocné třídy. Pokud přemýšlíte, do jaké složky je umístit, zkuste třeba `Accessory`:

/--pre
app/
├── UI/
│ ├── Admin/
│ │ ├── <b>Accessory/</b>
│ │ │ ├── FormFactory.php
│ │ │ └── AdminLayout.php
│ │ ├── Dashboard/
│ │ └── ...
\--


Vnořené moduly
--------------

Moduly nemusí tvořit jen plochou strukturu, lze vytvářet i submoduly, například:
Moduly nemusí představovat jen jednu úroveň zanoření. Stejně jako adresáře na disku je lze zanořovat hlouběji a vytvářet submoduly. Příklad:

/--pre
<b>app/</b>
├── <b>Modules/</b> ← adresář s moduly
app/
├── UI/
│ ├── <b>Blog/</b> ← modul Blog
│ │ ├── <b>Admin/</b> ← submodul Admin
│ │ │ ├── <b>Presenters/</b>
│ │ │ ├── Dashboard/
│ │ │ └── ...
│ │ ├── <b>Front/</b> ← submodul Front
│ │ │ ├── @layout.latte
│ │ │ ├── Home/
│ │ │ └── ...
│ │ └── <b>Front/</b> ← submodul Front
│ │ ├── <b>Presenters/</b>
│ │ └── ...
│ ├── <b>Forum/</b> ← modul Forum
│ │ └── ...
\--

Tedy modul `Blog` je rozdělen do submodulů `Admin` a `Front`. A opět se to odrazí na jmenných prostorech, které budou `App\Modules\Blog\Admin\Presenters` apod. Na presenter `Dashboard` uvnitř submodulu se odkazujeme jako `Blog:Admin:Dashboard`.
Tedy modul `Blog` je rozdělen do submodulů `Admin` a `Front`. A opět se to odrazí na jmenných prostorech, které budou `App\UI\Blog\Admin` a podobně. Na presenter `Dashboard` uvnitř submodulu se odkazujeme jako `Blog:Admin:Dashboard`.

Zanořování může pokračovat libovolně hluboko, lze tedy vytvářet sub-submoduly.

Pokud se vám například v administraci sejde větší počet presenterů pro správu objednávek (`OrderDetail`, `OrderEdit`, `OrderDispatch`, ...), můžete pro lepší přehlednost vytvořit modul `Order` a v něm mít presentery `Detail`, `Edit`, `Dispatch` atd.


Vytváření odkazů
----------------
Expand Down Expand Up @@ -104,44 +120,57 @@ Mapování

Definuje pravidla, podle kterých se z názvu presenteru odvodí název třídy. Zapisujeme je v [konfiguraci|configuration] pod klíčem `application › mapping`.

Začněme ukázkou, která moduly nepoužívá. Budeme jen chtít, aby třídy presenterů měly jmenný prostor `App\Presenters`. Tedy aby se presenter například `Home` mapoval na třídu `App\Presenters\HomePresenter`. Toho lze docílit následující konfigurací:
Všechny příklady, které jsme uváděli v této kapitole, předpokládají toto mapování:

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

Ale pro lepší pochopení začneme ukázkou aplikace, která nepoužívá moduly. Budeme jen chtít, aby třídy presenterů patřily do jmenného prostoru `App\UI`. Tedy aby se presenter `Home` mapoval na třídu `App\UI\HomePresenter`. Toho lze docílit následující konfigurací:

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

Název presenteru se nahradí za hvezdičku v masce třídy a výsledkem je název třídy. Snadné!
Název presenteru `Home` se nahradí za hvezdičku v masce třídy `App\UI\*Presenter` a máme výsledný název třídy `App\UI\HomePresenter`. Snadné!

Nicméně jak vidíte v ukázkách v této a dalších kapitolách, třídy presenterů se umisťují ještě do eponymních podadresářů, tj. presenter `Home` se mapuje na třídu `App\UI\Home\HomePresenter`. To zajistí zdvojená dvojtečka (vyžaduje Nette Application 3.2):

Pokud presentery členíme do modulů, můžeme pro každý modul mít vlastní mapování:
```neon
application:
mapping: App\UI\**Presenter
```

A nyní presentery rozčleníme do modulů. Pro každý modul můžeme definovat vlastní mapování:

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

Nyní se presenter `Front:Home` mapuje na třídu `App\Modules\Front\Presenters\HomePresenter` a presenter `Admin:Dashboard` na třídu `App\Modules\Admin\Presenters\DashboardPresenter`.
Tato konfigurace říká, že presenter `Front:Home` se mapuje na třídu `App\UI\Front\Home\HomePresenter`, zatímco třeba presenter `Api:OAuth` na třídu `App\Api\OAuthPresenter`.

Praktičtější bude vytvořit obecné (hvězdičkové) pravidlo, které první dvě nahradí. V masce třídy přibude hvezdička navíc právě pro modul:
Protože moduly `Front` i `Admin` mají podobný způsob mapování a takových modulů bude nejspíš více, dá se vytvořit obecné pravidlo, které tyto dvě nahradí. V masce třídy nám přibude hvezdička navíc právě pro modul:

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

Ale co když používáme vícenásobně zanořené moduly a máme třeba presenter `Admin:User:Edit`? V takovém případě se segment s hvězdičkou představující modul pro každou úroveň jednoduše zopakuje a výsledkem bude třída `App\Modules\Admin\User\Presenters\EditPresenter`.
Ale co když používáme vícenásobně zanořené moduly a máme třeba presenter `Admin:User:Edit`? V takovém případě se segment s hvězdičkou představující modul pro každou úroveň jednoduše zopakuje a výsledkem bude 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:

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

Výchozí hodnotou je `*Module\*Presenter`.

0 comments on commit 37af13f

Please sign in to comment.