vrátil jsem se k jednomu svému projektu, kde mám kód rozdělený hezky
do jednotlivých modulů, možná ale až moc :-) Mám totiž například
namespace app/Module/Member/Front a na této úrovni mi začínají
presentery (pak to je dále členěné třeba na formuláře, komponenty, atd.,
o úroveň výš je „Admin“).
Super je, že mám na celý web jenom dvě routy a URL adresy mám tak, jak
chci. Co mi ale hrozně vadí je, že mám tolik „Default“ presenterů,
kolik je modulů a ještě víc souborů default.latte :-) takže z tohohle
pohledu se v tom nedá vůbec vyznat, otázka je, co s tím?
Přejmenovat Default presentery podle názvu modulu? Budou mi pak stačit
jenom dvě routy? (Možná přepisovat výchozí presenter podle názvu modulu?)
Měl byste pro mě někdo nějaký tip či inspiraci, jak (třeba jinak)
to řešit?
HonzaN: Z ceho usuzujes, ze podrizuju strukturu pozadovane URL? Ja jen
nechtel mit pro kazdy takovy modul routu.
Ja ten modul tehda pojal tak, ze by to byl treba Git submodul (ano, i ted se
mi vic libi Git submodul nez balicek pridany pres composer). Tzn. napriklad
modul “Clen” / “Member”, kde bude zakladni prace s uzivatelama, od
registrace, prihlaseni, vypis uzivatelu, jejich formulare… a i ted po letech
mi to prijde jako spravna myslenka, kdy za pomoci jenom dvou rout ziskam funkcni
vsechny moduly na prijemne a pro me logicke adrese (uzivatele a
uzivatele/243-nick).
Takovy modul pak jednoduse prenesu do jineho projektu, aktualizuju a bude
fungovat. Zkusil jsem to resit pomoci globalnich filtru a zprovoznil jsem to,
jenom “nevyhoda” pri tvoreni odkazu na vstupni presenter modulu je, ze jsou
ve tvaru :Member:Member:
Ja jedu oddeleny Model od UI, takze mam App\Model\Members,
App\UI\Front\Members a App\UI\Admin\Members.
Taky jsem chtel mit App\Members a pod tim Model a
UI s tim, ze z toho budu mit balicek. Ale proste v zadnem
projektu to neni nikdy stejne, nekdo tam chce mit email, nekdo nick, atd.
Front je pak u kazdyho projektu uplne jinej, treba na Homepage jsou vetsinou
data ze 3 a vice modulu (Aktuality, Ankety, Produkty, atd.) a kam bych to asi
tak mel zaradit?
To máš pravdu, že častokrát to není stejné, pokud se tvoří hodně
projektů. Taky jsem pracoval na místech, kde každý projekt byl trochu jinak.
Ale řešil bych to tak, že existuje nějaký základ, z toho se vyjde (a
jestli je to potřeba upravit, tak to buď bude napsané tak, že mi to umožní
změny a nebo to nebude zpětně kompatibilní).
Já se pak v projektu líp orientuju a hned vidím, co kam patří.
HonzaN
To, že mám komponenty a formuláře v různých modulech mi přece nebrání
je použít v jiných, vůbec tím limitován nejsem.
Ja mam treba u klasickeho webu, jako treba eshop s administraci frontend
delany primo, jakoby bez modulu …
$shop = new RouteList()
… a Administraci pak jako modul …
$backend = new RouteList(‚Admin‘);
… podle toho mam i adresarovou sturkturu.
Delam to tak jednoduse proto, ze kdyz jsem mel modul eshop a modul admin, tak
jsem to tak mel i rozdelene do adresaru (co je teda pravda ze asi byt nemusi),
a pak jsem se musel hluboko preklikavat, co nemam moc rad.
V modulu Admin mam pak jen Components + Presenters a v nem Templates
Mám udělaný pouze základ projektu, kde mám 2 základní moduly Front a
Backend a podle potřeb to rozšiřují a pokud to není nutné tak
nevytvářím zbytečně další adresáře…
Kdysi jsem měl něco podobného, každý modul jsem měl zvlášť a v něm
vše co potřebuje, co mě na tom nejvíce štvalo bylo to hluboké
rozklikávání, dlouhý strom adresářů a nepřehlednost, tak jsem si udělal
jen dva základní moduly, 2 routy a namespace u modulů mám jen
Module/Front, Module/Admin. Vše má své výhody a nevýhody a záleží
hlavně na tom, jak to bude vyhovovat tobě.
Mám udělaný pouze základ projektu, kde mám 2 základní moduly Front a
Backend a podle potřeb to rozšiřují a pokud to není nutné tak
nevytvářím zbytečně další adresáře…
Kdysi jsem měl něco podobného, každý modul jsem měl zvlášť a v něm
vše co potřebuje, co mě na tom nejvíce štvalo bylo to hluboké
rozklikávání, dlouhý strom adresářů a nepřehlednost, tak jsem si udělal
jen dva základní moduly, 2 routy a namespace u modulů mám jen
Module/Front, Module/Admin. Vše má své výhody a nevýhody a záleží
hlavně na tom, jak to bude vyhovovat tobě.
Takhle jsem to taky delaval, ale pak me stvalo, tak jsem zacal pouzivat tuhle
strukturu: https://prnt.sc/skv2cp
Hlavni web je hned v app a admin je ve vlastnim adresari
jasně, proč ne, jen si dej pozor na velké názvy adresářů pokud k ním
zadáváš cestu. Vzpomínám na kolegu, který vyvíjel na windowsu a po
přesunu projektu na linux mu to nenašlo cesty k šablonám od komponent a
docela s tím bojoval :)
jasně, proč ne, jen si dej pozor na velké názvy adresářů pokud k ním
zadáváš cestu. Vzpomínám na kolegu, který vyvíjel na windowsu a po
přesunu projektu na linux mu to nenašlo cesty k šablonám od komponent a
docela s tím bojoval :)
Ja s tim problem nemam … Vyvyjim na MAC a na hostingu jsem zatim probelm
nemel, ale jednou po mne kolega, ktery bezi na linuxe delal na projektu a dost
nadaval no :D
Ještě to tu trochu oživím, pokud se snažím psát presentery tak, aby
toho v nich bylo co nejméně, pak ke každému takovému presenteru náleží
šablona default.latte. Pokud uvedu na příkladu eshopu, tak
třeba CatalogPresenter.php → default.latte (výpis
produktů). Dál ProductPresenter.php →
default.latte. Pak je všechno jenom default.latte a
špatně se v tom orientuje, ne? Jak to řešíte prakticky?
Je to asi takhle:
Máš presenter, např. ProductPresenter a akci (view)
show, pak presenter má název ProductPresenter.php a
šablona má název show.latte.
Ale v presenteru musíš použít místo metody action() metodu
actionShow() a místo metody render() metodu
renderShow().
V dokumentaci viz zde https://doc.nette.org/…n/presenters#…
a zde https://doc.nette.org/…n/presenters#…
IJVo
(Myslím, že za těch 10 let, co Nette znám, to už mám trochu naučené
:-D)
Ale děkuji, já to nenapsal úplně jasně. Jde mi o to, že pokud udělám co
nejmenší presentery, třeba Homepage, Article, ArticleList, About, Contact,
tak ve výchozím stavu mají jako view šablonu default.latte. A pak když
chci v IDE do nějaké šablony, mám vypsáno třeba 30 souborů, které se
jmenují default.latte. Proto by mě zajímalo, jak toto kdo řeší. Možná by
bylo lepší mít název šablony jako název presenteru. (Koukám po takovém
best practice).
A nestačí je jenom nepojmenovávat default.latte, ale jakkoliv jinak? Pak
pořád můžeš mít na jeden presenter jednu akci, ale zároveň nebudeš mít
30× default.latte. Nikdo ti přece nebrání mít v ArticleListPresenter.php
metodu renderArticleList(…).
Btw jakou výhodu podle tebe má mít jenom jednu akci v presenteru? Já to
vždy dělal tak, že když jsem měl třeba ProductPresenter, tak má v sobě
metody jako renderList, renderDetail, renderCreate/Update atd. Co má za výhodu
mít na to samostatnej presenter?
@joe
Já jsem si docela oblíbil šablony pojmenovávat ve formátu
Homepage.default.latte nebo treba Article.show.latte
(presenter.view.latte). Funguje to bez jakéhokoliv nastavování. Je to podle
mě přehlednější a vyhledávání v IDE je lehčí :)
Díky, ten delší způsob pojmenování se mi tolik nelíbí, i když je to
taky cesta. Pořád to je taková honba za dokonalostí a tím, co se mi bude
líbit :) asi si to vymyslím tak, že
Btw jakou výhodu podle tebe má mít jenom jednu akci v presenteru?
mas mensi a prehlednejsi presentery, mas tam pouze
zavislosti/komponenty/signaly pro tu danou akci a ne pro 5 dalsich.
Tak z meho pohledu:
nedodrzuju PSR4
pouzivam melkou strukturu modulu (tedy jen admin/front, pripadne dalsi
„entrypointy“)
ale v nich si delam slozky, jak uznam za vhodne (takze si tam udelam slozku
„Product“, kam nahazim vsechny presentery, ktery souviseji s produkty)
pouzivam single action presentery – mam i zakazane jine nez default akce
(kontrola ve startupu). porad se ale muze zmenit view
mam upraveny formatovani action a render metod, aby tam nebyl ten suffix
„default“
mam upraveny formatovani nazvu sablon a povoluju pouze jeden format (podobne
jako pise @joe), tedy pro ProductDetailPresenter je sablona
ProductDetail.latte v pripade default view, pokud view zmenim, tak
ProductDetail-foo.latte
k layoutu mam presne zadefinovanou cestu v base presenteru
(ty posledni dva body, krom toho, ze vyzaduji konzistenci, tak maji
i pozitivni dopad na vykon, jelikoz se nemusi delat
IO operace)
Snažím se, aby presenter dělal jen jednu věc. Ale, pokud se bavíme
o takové té klasické „ORM“ struktuře, tak za tu jednu věc považuji
starat se o jednu entitu.
Takže (klasický profláklý příklad) jeden presenter řeší třeba
články. ArticlePresenter
– (action/render) preview na adrese
Article:preview, tedy article/preview
– detail
– new
– edit
– delete (toto je handle)
Kromě toho obsahuje createComponentNewForm a
createComponentEditForm. Formuláře se vytvářejí v externí
továrně a data zpracovává model. Takže presenter dělá jen prostředníka
mezi modelem a šablonou, řeší flashmessages, občas jazyk a ajax.
V čem doteď nemám jasno, jestli je lepší mít i metodu
list (Article:list), tedy seznam článků. Anebo mít
samostatny ArticlesPresenter, který má typicky jen ten jeden
pohled list.
Výhodou všeho v jednom presenteru je, že z výpisu článků mohu volat
handleDelete, což v externím presenteru nejde (nešlo? už jsem
na to nějakou dobu nekoukal). Edit: Jop, odkaz na
signál z jiného presenteru nejde. Takže je potřeba napsat si signál
v ArticlesPresenteru, což je ale už zase práce s jedním článkem, nikoliv
kolekcí.
Nevýhodou je, že už je to přecijen něco jiného. Kolekce článů,
filtrování, listování, gridy – to všechno už s článkem jako takovým
nemá moc společného. A ten jeden presenter tím docela nabobtná. (I když
stále má okolo 100 řádků, pokud tam není nějaké složité řešeni
ajaxu, nebo nějaké triggerováni formulářů na základě persistentních
parametrů apod.)
PSR4 beru jako standart, je nějaký důvod nedodržovat?
Jinak mi přijde, že dává Nette dost na výběr, na jednu stranu to je
super :-), ale na druhou, že není nic striktního a všichni to nepíšou
stejně (zase ale chápu, že se někomu může líbit jiný způsob a nakonec
pro každý případ se může hodit zvolit trochu něco odlišného).
Šaman
Řešení traitama se ti v tomto případě nelíbí? Už to trochu ztrácí
na jednoduchosti. Případně nějakým CUD presenterem, ale od toho se
ustupuje, co jsem tak pochopil.
@joe je nějaký důvod (krom toho, že je to standart) to
dodržovat? :)
ne a vážně – dodržovat PSR dává smysl hlavně u opensource
projektů, aby to přispěvatelé měli snažší. u vlastního kódu se
snažím, abych to měl snažší já. a některé z výhod, které z toho
plynou:
snažší refaktoring – když to přesunu do jiný složky, tak se
nemusím starat o změnu namespace
méně importů
díky té mělké struktuře namespace máš často unikátní názvy tříd
a snadněji se v nich tak naviguješ – nemusíš zkoumat, v jakém
namespace jsou
@joe je nějaký důvod (krom toho, že je to standart) to
dodržovat? :)
ne a vážně – dodržovat PSR dává smysl hlavně u opensource
projektů, aby to přispěvatelé měli snažší. u vlastního kódu se
snažím, abych to měl snažší já. a některé z výhod, které z toho
plynou:
snažší refaktoring – když to přesunu do jiný složky, tak se
nemusím starat o změnu namespace
méně importů
díky té mělké struktuře namespace máš často unikátní názvy tříd
a snadněji se v nich tak naviguješ – nemusíš zkoumat, v jakém
namespace jsou
A já myslel, že PSR je standart, aby se v kódu šlo vyznat bez ohledu na
typ licence.
@DavidMatějka Tak mně to s tím PSR4 přijde přehlednější, že
to dá aspoň nějaký řád do kódu, bez ohledu na to, o jaký projekt jde.
Prostě je to pro mě určitý pořádek, stejně jako pojmenování souboru
podle názvu třídy, tak i namespace podle aktuálního umístění. Pokud je
to všechno v jednom namespace, ale rozmístěno do složek, jednoduše může
dojít kolizi názvů. A u většího projektu, kde je souborů třeba přes
300 mi to prostě dává smysl (a nikdy nevím, kdy se z jednoduchého
projektu stane složitý).
@Šaman Odkaz na signál v jiném presenteru sice nejde, ale jde
udělat odkaz na signál v jakékoli komponentě. To znamená vytvořím si
např. ArticleDeleteButtonControl, ve kterém bude handleDelete. A tu
komponentu si přidám do ArticlePresenteru pro daný článek.
V ArticlesPresenteru si vytvořím přes Multiplier jednu pro každý článek,
kde je potřeba.
@DavidMatějka Tak mně to s tím PSR4 přijde přehlednější, že
to dá aspoň nějaký řád do kódu, bez ohledu na to, o jaký projekt jde.
Prostě je to pro mě určitý pořádek, stejně jako pojmenování souboru
podle názvu třídy, tak i namespace podle aktuálního umístění. Pokud je
to všechno v jednom namespace, ale rozmístěno do složek, jednoduše může
dojít kolizi názvů. A u většího projektu, kde je souborů třeba přes
300 mi to prostě dává smysl (a nikdy nevím, kdy se z jednoduchého
projektu stane složitý).
Však o tom to je.
Prostě používej PSR, dřív nebo později se ti to vyplatí.
What are the aims of the PHP-FIG?
The idea behind the group is for project representatives to talk about the
commonalities between our projects and find ways we can work together. Our main
audience is each other, but we’re very aware that the rest of the PHP
community is watching. If other folks want to adopt what we’re doing they are
welcome to do so, but that is not the aim. Nobody in the group wants to
tell you, as a programmer, how to build your application.
on teda i ten název té pracovní skupiny by ti mohl napovědět: PHP
Framework Interop Group
What are the aims of the PHP-FIG?
The idea behind the group is for project representatives to talk about the
commonalities between our projects and find ways we can work together. Our main
audience is each other, but we’re very aware that the rest of the PHP
community is watching. If other folks want to adopt what we’re doing they are
welcome to do so, but that is not the aim. Nobody in the group wants to
tell you, as a programmer, how to build your application.
on teda i ten název té pracovní skupiny by ti mohl napovědět: PHP
Framework Interop Group
Možná, kdyby si svůj pohled na PSR charakterizoval jinak než
„dodržovat PSR dává smysl hlavně u opensource projektu“, tak by to dalo
větší smysl.
Programoval si někdy v týmu nebo pracoval na větším projektu, že máš
tenhlé názor na PSR?
U nás se vývojáři střidaj, podle toho kdo má čas a bez PSR by se
z toho stál guláš.
Když už egoistický mínusujete, můžete uvést důvod…
Dal jsem mínus, informační hodnota těch příspěvků je 0. Spíš
mínus. Fakt nechápu anonymní lidi, kteří mají potřebu volit
konfrontační formu a každý druhý příspěvek je urážka cizího názoru.
Diskuze vypadá jinak. Ať nováčci, kteří sem zavítají, vidí, že tohle
tady není standardní chování.
OT: Dovolím si použít hlášku z divadla Sklep… já kdybych napsal
něco takového, tak bych se pod taky nepodepsal.
Mám udělaný pouze základ projektu, kde mám 2 základní moduly Front a
Backend a podle potřeb to rozšiřují a pokud to není nutné tak
nevytvářím zbytečně další adresáře…
Kdysi jsem měl něco podobného, každý modul jsem měl zvlášť a v něm
vše co potřebuje, co mě na tom nejvíce štvalo bylo to hluboké
rozklikávání, dlouhý strom adresářů a nepřehlednost, tak jsem si udělal
jen dva základní moduly, 2 routy a namespace u modulů mám jen
Module/Front, Module/Admin. Vše má své výhody a nevýhody a záleží
hlavně na tom, jak to bude vyhovovat tobě.
Takhle jsem to taky delaval, ale pak me stvalo, tak jsem zacal pouzivat tuhle
strukturu: https://prnt.sc/skv2cp
Hlavni web je hned v app a admin je ve vlastnim adresari
Podobnou strukturu jsem chtěl teď použít, tzn. mít „globální“
presentery a pak část presenterů v modulu. Jak ale v Latte udělat pak
n:href na presenter, který není v modulu? Automaticky si to domýšlí
aktuální modul.
@jspetrak Základ je mít univerzální mapování presenterů
(v případě z https://prnt.sc/skv2cp myslím takto
*: ['App', '*', 'Presenters\*Presenter'])
Na presentery se pak dotazuješ pomocí absolutního názvu, ne
relativního – :Error:default,
:Admin:User:default apod.