Elegantnější strukturování presenterů

před rokem od David Grudl  

Máte rádi pořádek a strukturu? Když je všechno přesně tam, kde má být, a snadno se v tom orientujete? Kdo by neměl. Nette Framework 3.2 přináší nový způsob, jak organizovat presentery a jejich šablony ve vaší aplikaci.

Nette nyní umožňuje každému presenteru mít svůj vlastní samostatný adresář. To znamená, že všechny soubory týkající se konkrétního presenteru, od PHP souborů až po šablony Latte, můžete mít pohromadě v jedné složce. To usnadňuje navigaci ve vašem projektu a zvyšuje přehlednost.

Představte si tuto strukturu:

├── @layout.latte
├── Home/
│   ├── HomePresenter.php
│   ├── HomeTemplate.php
│   └── default.latte
├── Article/
│   ├── ArticlePresenter.php
│   ├── ArticleTemplate.php
│   ├── add.latte
│   └── edit.latte

Každý presenter má svou složku a v ní vše potřebné. Už žádné zdlouhavé dohledávání šablon v podadresářích.

Jak to funguje?

Díky novému zástupnému znaku ** v mapování můžete definovat, že presenter má být v eponymní složce:

application:
    mapping: App\Presentation\*\**Presenter

Toto nastavení zajistí, že například presenter Admin:Dashboard se bude mapovat na třídu App\Presentation\Admin\Dashboard\DashboardPresenter.

A co šablony?

Pokud chcete nadále umísťovat šablony do samostatné složky jako dosud, nemusíte se ničeho obávat. Nette nyní inteligentně hledá šablony jak ve složce templates, tak ve složce s presenterem, a to pokud adresář templates neexistuje.

Podobně to funguje s @layout.latte. Pokud adresář templates neexistuje, hledá se nejprve ve složce presenteru a poté ve složkách nadřazených. A to až podle úrovně zanoření modulu.

Jak začít používat tuto novinku?

Stačí jen upravit mapování a přesunout soubory. V PhpStormu nad názvem třídy stisknete F6 a můžete změnit namespace. Soubory se šablonami je potřeba přesunout ručně.

Tato adresářová struktura se používá také ve skeletonu nette/web-project. Složkou, která obsahuje všechny presentery, jejich šablony a případné pomocné třídy, je App\Presentation. Není to obvyklé Module, protože takový název není příliš vypovídající a zároveň je hodně podobný používanému Model. Alternativní vhodný název by byl App\UI. Pokud uvažujete, kam zařadit různé další pomocné třídy, zvažte využití složky Accessory:

app/
├── Presentation/
│   ├── Accessory/
│   │   ├── FormFactory.php
│   │   └── AdminLayout.php
│   ├── Dashboard/
│   │   ├── DashboardPresenter.php
│   │   └── default.latte
│   └── ...

Tato metoda nejen zjednodušuje organizaci souborů, ale také je v souladu s moderními postupy kódování, protože činí strukturu aplikace modulárnější a snadněji udržovatelnou.

Komentáře

  1. Tak tohle se mi brutalne libi! Okamzite jsem to na aktualnim projektu poprehazel a ted je to uz uplne o necem jinem! Ted je to prehledne! Skvele! Diky!!

    před rokem
  2. Je to pěkné. Jen mě trochu dráždí, když už jsem se do toho úklidu dal, že se Accessory míchá s ostatními složkami + neměl jsem kam dát soubory s šablonami, které vkládám do hl. @layout.latte (je jich hodně na to je nechat ležet vedle). Prozatím jsem to vyřešil tím, že mám UI/_accessory a UI/_templates, ale něco mi říká, že úplně 100% to není. Nějaké nápady?

    před rokem · replied [6] NeonMind
  3. Tohle je super! 👏 Používám tuto „feature“ based strukturu v projektech a je to prostě efektivní.

    před rokem
  4. A pro single action prezenter takto?

    app/
    ├── UI/
    │ ├── Article/
    │ │ ├── ShowPresenter.php
    │ │ ├── AddPresenter.php
    │ │ ├── EditPresenter.php
    │ │ ├── templates/
    │ │ │ ├── Show/
    │ │ │ │ └── default.latte
    │ │ │ ├── Add/
    │ │ │ │ └── default.latte
    │ │ │ └── Edit/
    │ │ │ └── default.latte
    │ ├── Accessory/
    │ │ ├── FormFactory.php
    │ │ └── SomeHelperClass.php
    ├── Model/
    │ ├── Article.php
    │ └── ArticleRepository.php
    config/
    ├── common.neon
    ├── local.neon

    před 11 měsíci
  5. Co se nachází v těch HomeTemplate.php a ArticleTemplate.php?

    před 9 měsíci
  6. #2 micmar Taky mi nevoní míchání /Accessory s názvy presenterů. Podtržítko to řeší, ale tak nějak upatlaně. Ale jak to řešit lépe netuším.

    před 7 měsíci
  7. Několik dní jsem se snažil rozjet mapping a routy pro podobné rozložení. O týden později jsem našel tento článek :)

    použil jsem tento mapping
    mapping:
    : [‚Api‘, ‚‘, ‚**Presenter‘]
    Ale mám ještě trochu jinou strukturu abych oddělil společné věci a bylo to PSR-4 friendly. V Common mám basePresenter, baseService, auth traity, chyby a další (společné) věci. Je to Api, takže middleware, ale mám to podobně i pro Front, kde by se dalo předpokládat existenci komponent a dalších věcí.
    Jediné co je třeba v routách přistupovat pomocí
    $router->addRoute(‚projects/‘, ‚Modules:Projects:default‘);
    Stejně tak mám samostatně docker na api a front, ale při dvou modulech v jednom prostředí bych předpokládal jen mít 2× mapping pro Api: [ a App: [ a do routy jen přidat Api:Modules:.....
    Ale musel jsem si upravit v BasePresenteru načítání template.

    Moje struktura
    .
    ├── Common
    │   ├── Entity
    │   ├── Errors
    │   │   └── Templates
    │   ├── Facade
    │   │   └── Trait
    │   ├── Middleware
    │   ├── Presenter
    │   │   └── Trait
    │   ├── Repository
    │   ├── Router
    │   ├── Security
    │   └── Service
    ├── Modules
    │   ├── Auth
    │   ├── Default
    │   │   └── Templates
    │   └── Projects
    │   ├── Entity
    │   ├── Facade
    │   ├── Repository
    │   └── Service
    └── config

    před 17 dny
  8. .. koukám hvězdičky se mi nepřepsaly správně v mapping. tak snad teď
    mapping:
    *: [\‚App\‘, \‚*\‘, \‚*\\*Presenter‘]

    před 17 dny

Chcete-li odeslat komentář, přihlaste se