Skip to content

Commit

Permalink
new directory structure [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Apr 18, 2024
1 parent 8344e4c commit 50766d0
Show file tree
Hide file tree
Showing 17 changed files with 88 additions and 89 deletions.
14 changes: 7 additions & 7 deletions application/cs/how-it-works.texy
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ Adresářová struktura vypadá nějak takto:
/--pre
<b>web-project/</b>
├── <b>app/</b> ← adresář s aplikací
│ ├── <b>Presenters/</b> ← presentery a šablony
│ │ ── <b>HomePresenter.php</b> ← třída presenteru Home
│ └── <b>templates/</b> ← adresář se šablonami
│ │ ├── <b>@layout.latte</b> ← šablona layoutu
└── <b>Home/</b> ← šablony presenteru Home
── <b>default.latte</b> ← šablona akce 'default'
── <b>Router/</b> ← konfigurace URL adres
│ ├── <b>Core/</b> ← základní systémové třídy
│ │ ── <b>RouterFactory.php</b> ← konfigurace URL adres
── <b>UI/</b> ← presentery, šablony a pomocné třídy
│ │ ├── <b>@layout.latte</b> ← šablona layoutu
│ └── <b>Home/</b> ← adresář presenteru Home
── <b>HomePresenter.php</b> ← třída presenteru Home
│ └── <b>default.latte</b> ← šablona akce 'default'
│ └── <b>Bootstrap.php</b> ← zaváděcí třída Bootstrap
├── <b>bin/</b> ← skripty spouštěné z příkazové řádky
├── <b>config/</b> ← konfigurační soubory
Expand Down
45 changes: 23 additions & 22 deletions application/cs/modules.texy
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ Zapomeňme tedy na jednu složku pro presentery a šablony a místo toho vytvoř

/--pre
<b>app/</b>
├── <del>Presenters/</del>
├── <b>Modules/</b> ← adresář s moduly
├── <b>UI/</b> ← presentery, šablony a pomocné třídy
├── <b>@layout.latte</b> ← šablona layoutu
│ ├── <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
│ │ │ ├── <b>Dashboard/</b>
│ │ │ │ └── <b>DashboardPresenter.php</b>
│ ├── <b>Front/</b> ← modul Front
│ │ ├── <b>Home/</b> ← adresář presenteru Home
│ │ │ ├── <b>HomePresenter.php</b> ← třída presenteru Home
│ │ │ └── <b>default.latte</b> ← šablona akce 'default'
│ └── ...
\--

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,7 +34,7 @@ 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.
A jak Nette vlastní ví, že `Admin:Dashboard` představuje třídu `App\UI\Admin\Dashboard\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.
Expand All @@ -46,19 +47,19 @@ Moduly nemusí tvořit jen plochou strukturu, lze vytvářet i submoduly, např

/--pre
<b>app/</b>
├── <b>Modules/</b> ← adresář s moduly
├── <b>UI/</b> ← presentery, šablony a pomocné třídy
│ ├── <b>Blog/</b> ← modul Blog
│ │ ├── <b>Admin/</b> ← submodul Admin
│ │ │ ├── <b>Presenters/</b>
│ │ │ ├── <b>Dashboard/</b>
│ │ │ └── ...
│ │ └── <b>Front/</b> ← submodul Front
│ │ ├── <b>Presenters/</b>
│ │ ├── <b>Home/</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\...` apod. 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.

Expand Down Expand Up @@ -104,11 +105,11 @@ 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í:
Začněme ukázkou, která moduly nepoužívá. Budeme jen chtít, aby třídy presenterů měly jmenný prostor `App\UI`. Tedy aby se presenter například `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é!
Expand All @@ -118,30 +119,30 @@ Pokud presentery členíme do modulů, můžeme pro každý modul mít vlastní
```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`.
Nyní se presenter `Front:Home` mapuje na třídu `App\UI\Front\HomePresenter` a presenter `Admin:Dashboard` na třídu `App\UI\Admin\DashboardPresenter`.

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:

```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\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]
```

Výchozí hodnotou je `*Module\*Presenter`.
10 changes: 5 additions & 5 deletions application/cs/routing.texy
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,10 @@ $router->addRoute('index<?.html \.html?|\.php|>', /* ... */);
Začlenění do aplikace
=====================

Abychom vytvořený router zapojili do aplikace, musíme o něm říci DI kontejneru. Nejsnazší cesta je připravit továrnu, která objekt routeru vyrobí, a sdělit v konfiguraci kontejneru, že ji má použít. Dejme tomu, že k tomu účelu napíšeme metodu `App\Router\RouterFactory::createRouter()`:
Abychom vytvořený router zapojili do aplikace, musíme o něm říci DI kontejneru. Nejsnazší cesta je připravit továrnu, která objekt routeru vyrobí, a sdělit v konfiguraci kontejneru, že ji má použít. Dejme tomu, že k tomu účelu napíšeme metodu `App\Core\RouterFactory::createRouter()`:

```php
namespace App\Router;
namespace App\Core

use Nette\Application\Routers\RouteList;

Expand All @@ -499,7 +499,7 @@ Do [konfigurace |dependency-injection:services] pak zapíšeme:

```neon
services:
- App\Router\RouterFactory::createRouter
- App\Core\RouterFactory::createRouter
```

Jakékoliv závislosti, třeba na databázi atd, se předají tovární metodě jako její parametry pomocí [autowiringu|dependency-injection:autowiring]:
Expand Down Expand Up @@ -663,7 +663,7 @@ Samostatným použitím myslíme využití schopností routeru v aplikaci, kter
Takže opět si vytvoříme metodu, která nám sestaví router, např.:

```php
namespace App\Router;
namespace App\Core;

use Nette\Routing\RouteList;

Expand Down Expand Up @@ -694,7 +694,7 @@ $httpRequest = $container->getByType(Nette\Http\IRequest::class);
Anebo objekty přímo vyrobíme:

```php
$router = App\Router\RouterFactory::createRouter();
$router = App\Core\RouterFactory::createRouter();
$httpRequest = (new Nette\Http\RequestFactory)->fromGlobals();
```

Expand Down
6 changes: 3 additions & 3 deletions application/cs/templates.texy
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Anotace `@property-read` je určená pro IDE a statickou analýzu, díky ní bud
Luxusu našeptávání si můžete dopřát i v šablonách, stačí do PhpStorm nainstalovat plugin pro Latte a uvést na začátek šablony název třídy, více v článku "Latte: jak na typový systém":https://blog.nette.org/cs/latte-jak-na-typovy-system:

```latte
{templateType App\Presenters\ArticleTemplate}
{templateType App\UI\Article\ArticleTemplate}
...
```

Expand Down Expand Up @@ -176,7 +176,7 @@ public function beforeRender(): void
Latte ve verzi 3 nabízí pokročilejší způsob a to vytvoření si [extension |latte:creating-extension] pro každý webový projekt. Kusý příklad takové třídy:

```php
namespace App\Templating;
namespace App\UI\Accessory;

final class LatteExtension extends Latte\Extension
{
Expand Down Expand Up @@ -214,7 +214,7 @@ Zaregistrujeme ji pomocí [konfigurace |configuration#Šablony Latte]:
```neon
latte:
extensions:
- App\Templating\LatteExtension
- App\UI\Accessory\LatteExtension
```


Expand Down
2 changes: 1 addition & 1 deletion best-practices/cs/composer.texy
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ Nicméně je možné používat Composer i pro načítání dalších tříd i m

Následně je potřeba při každé změně spustit příkaz `composer dumpautoload` a nechat autoloadovací tabulky přegenerovat. To je nesmírně nepohodlné a daleko lepší je tento úkol svěřit [RobotLoaderu|robot-loader:], který stejnou činnost provádí automaticky na pozadí a mnohem rychleji.

Druhou možností je dodržovat [PSR-4|https://www.php-fig.org/psr/psr-4/]. Zjednodušeně řečeno jde o systém, kdy jmenné prostory a názvy tříd odpovídají adresářové struktuře a názvům souborů, tedy např. `App\Router\RouterFactory` bude v souboru `/path/to/App/Router/RouterFactory.php`. Příklad konfigurace:
Druhou možností je dodržovat [PSR-4|https://www.php-fig.org/psr/psr-4/]. Zjednodušeně řečeno jde o systém, kdy jmenné prostory a názvy tříd odpovídají adresářové struktuře a názvům souborů, tedy např. `App\Core\RouterFactory` bude v souboru `/path/to/App/Core/RouterFactory.php`. Příklad konfigurace:

```js
{
Expand Down
10 changes: 4 additions & 6 deletions best-practices/cs/pagination.texy
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace App\Model;

use Nette;


class ArticleRepository
{
public function __construct(
Expand All @@ -34,7 +33,7 @@ class ArticleRepository
V presenteru si pak injectujeme modelovou třídu a v render metodě si vyžádáme publikované články, které předáme do šablony:

```php
namespace App\Presenters;
namespace App\UI\Home;

use Nette;
use App\Model\ArticleRepository;
Expand All @@ -53,7 +52,7 @@ class HomePresenter extends Nette\Application\UI\Presenter
}
```

V šabloně se pak postaráme o výpis článků:
V šabloně `default.latte` se pak postaráme o výpis článků:

```latte
{block content}
Expand Down Expand Up @@ -114,7 +113,7 @@ Následně se pustíme do úprav presenteru. Do render metody budeme předávat
Dále také render metodu rozšíříme o získání instance Paginatoru, jeho nastavení a výběru správných článků pro zobrazení v šabloně. HomePresenter bude po úpravách vypadat takto:

```php
namespace App\Presenters;
namespace App\UI\Home;

use Nette;
use App\Model\ArticleRepository;
Expand Down Expand Up @@ -190,7 +189,6 @@ namespace App\Model;

use Nette;


class ArticleRepository
{
public function __construct(
Expand All @@ -210,7 +208,7 @@ class ArticleRepository
V presenteru nemusíme vytvářet Paginator, použijeme místo něj metodu třídy `Selection`, kterou nám vrací repositář:

```php
namespace App\Presenters;
namespace App\UI\Home;

use Nette;
use App\Model\ArticleRepository;
Expand Down
2 changes: 1 addition & 1 deletion dependency-injection/cs/configuration.texy
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Jak upravit hromadně všechny služby určitého typu? Třeba zavolat určitou
```neon
decorator:
# u všech služeb, co jsou instancí této třídy nebo rozhraní
App\Presenters\BasePresenter:
App\UI\BasePresenter:
setup:
- setProjectId(10) # zavolej tuto metodu
- $absoluteUrls = true # a nastav proměnnou
Expand Down
2 changes: 1 addition & 1 deletion dependency-injection/cs/factory.texy
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ Druhou možností je využít k definici [tagy|services#Tagy]:

```neon
services:
- App\Router\RouterFactory::createRouter
- App\Core\RouterFactory::createRouter
- App\Model\DatabaseAccessor(
db1: @database.db1.explorer
)
Expand Down
4 changes: 2 additions & 2 deletions forms/cs/in-presenter.texy
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Formulář v presenteru je objekt třídy `Nette\Application\UI\Form`, její př

Z pohledu presenteru je formulář běžná komponenta. Proto se s ním jako s komponentou zachází a začleníme ji do presenteru pomocí [tovární metody |application:components#Tovární metody]. Bude to vypadat takto:

```php .{file:app/Presenters/HomePresenter.php}
```php .{file:app/UI/Home/HomePresenter.php}
use Nette;
use Nette\Application\UI\Form;

Expand Down Expand Up @@ -59,7 +59,7 @@ class HomePresenter extends Nette\Application\UI\Presenter

A v šabloně formulář vykreslíme značkou `{control}`:

```latte .{file:app/Presenters/templates/Home/default.latte}
```latte .{file:app/UI/Home/default.latte}
<h1>Registrace</h1>

{control registrationForm}
Expand Down
14 changes: 7 additions & 7 deletions quickstart/cs/authentication.texy
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ Nyní máme autentifikaci připravenu a musíme připravit uživatelské rozhran

Začneme s přihlašovacím formulářem. Již víme, jak formuláře v presenterech fungují. Vytvoříme si tedy presenter `SignPresenter` a zapíšeme metodu `createComponentSignInForm`. Měl by vypadat nějak takto:

```php .{file:app/Presenters/SignPresenter.php}
```php .{file:app/UI/Sign/SignPresenter.php}
<?php
namespace App\Presenters;
namespace App\UI\Sign;

use Nette;
use Nette\Application\UI\Form;
Expand Down Expand Up @@ -62,7 +62,7 @@ Jsou zde políčka pro uživatelské jméno a heslo.

Formulář se bude vykreslovat v šabloně `in.latte`:

```latte .{file:app/Presenters/templates/Sign/in.latte}
```latte .{file:app/UI/Sign/in.latte}
{block content}
<h1 n:block=title>Přihlášení</h1>

Expand All @@ -77,7 +77,7 @@ Dále doplníme callback pro přihlášení uživatele, který bude volán hned

Callback pouze převezme uživatelské jméno a heslo, které uživatel vyplnil a předá je authenticatoru. Po přihlášení přesměrujeme na úvodní stránku.

```php .{file:app/Presenters/SignPresenter.php}
```php .{file:app/UI/Sign/SignPresenter.php}
private function signInFormSucceeded(Form $form, \stdClass $data): void
{
try {
Expand All @@ -102,7 +102,7 @@ Zabezpečíme formulář pro přidávání a editování příspěvků. Ten je d

Vytvoříme metodu `startup()`, která se spouští ihned na začátku [životního cyklu presenteru|application:presenters#zivotni-cyklus-presenteru]. Ta přesměruje nepřihlášené uživatele na formulář s přihlášením.

```php .{file:app/Presenters/EditPresenter.php}
```php .{file:app/UI/Edit/EditPresenter.php}
public function startup(): void
{
parent::startup();
Expand Down Expand Up @@ -139,7 +139,7 @@ Odkaz na přihlášení

Jak se vlastně dostaneme na přihlašovací stránku? Není zde žádný odkaz, který by na ni vedl. Tak si ho tedy přidáme do šablony `@layout.latte`. Pokuste se najít vhodné místo - může to být téměř kdekoliv.

```latte .{file:app/Presenters/templates/@layout.latte}
```latte .{file:app/UI/@layout.latte}
...
<ul class="navig">
<li><a n:href="Home:">Články</a></li>
Expand All @@ -156,7 +156,7 @@ Pokud není uživatel přihlášen, zobrazí se odkaz "Přihlásit". V opačném

Jelikož uživatele po odhlášení okamžitě přesměrujeme, není potřeba žádná šablona. Odhlášení vypadá takto:

```php .{file:app/Presenters/SignPresenter.php}
```php .{file:app/UI/Sign/SignPresenter.php}
public function actionOut(): void
{
$this->getUser()->logout();
Expand Down
Loading

0 comments on commit 50766d0

Please sign in to comment.