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 ab78169
Show file tree
Hide file tree
Showing 18 changed files with 102 additions and 103 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í třídy nutné pro chod
│ │ ── <b>RouterFactory.php</b> ← konfigurace URL adres
── <b>UI/</b> ← presentery, šablony & spol.
│ │ ├── <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
10 changes: 5 additions & 5 deletions quickstart/cs/@home.texy
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ Web Project má následující strukturu:
/--pre
<b>nette-blog/</b>
├── <b>app/</b> ← adresář s aplikací
│ ├── <b>Presenters/</b> ← třídy presenterů
│ │ └── <b>templates/</b>← šablony
│ ├── <b>Router/</b> ← konfigurace URL adres
│ ├── <b>UI/</b> ← presentery, šablony & spol.
│ │ └── <b>Home/</b> ← adresář presenteru Home
│ ├── <b>Core/</b> ← základní třídy nutné pro chod
│ └── <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 All @@ -67,7 +67,7 @@ Nejdůležitější složka je pro nás `app/`. Zde nalezneme soubor `Bootstrap.
Úklid
=====

Web Project obsahuje úvodní stránku, kterou smažeme předtím, než začneme něco programovat. Bez obav tedy nahradíme obsah souboru `app/Presenters/templates/Home/default.latte` za "Hello world!".
Web Project obsahuje úvodní stránku, kterou smažeme předtím, než začneme něco programovat. Bez obav tedy nahradíme obsah souboru `app/UI/Home/default.latte` za "Hello world!".


[* qs-hello.webp .{url:-} *]
Expand All @@ -76,7 +76,7 @@ Web Project obsahuje úvodní stránku, kterou smažeme předtím, než začneme
Tracy (debugger)
================

Extrémně důležitý nástroj pro vývoj je [ladicí nástroj Tracy |tracy:]. Vyzkoušejte si vyvolání nějaké chyby v souboru `app/Presenters/HomePresenter.php` (např. odstraněním složené závorky v definici třídy HomePresenter) a podívejte se, co se stane. Vyskočí oznamovací stránka, která chybu srozumitelně popisuje.
Extrémně důležitý nástroj pro vývoj je [ladicí nástroj Tracy |tracy:]. Vyzkoušejte si vyvolání nějaké chyby v souboru `app/UI/Home/HomePresenter.php` (např. odstraněním složené závorky v definici třídy HomePresenter) a podívejte se, co se stane. Vyskočí oznamovací stránka, která chybu srozumitelně popisuje.

[* qs-tracy.webp .{url:-}(debugger screen) *]

Expand Down
Loading

0 comments on commit ab78169

Please sign in to comment.