Routovanie – výrazy v maskách vz. názvy premenných v metódach
- Čamo
- Člen | 798
Príjemné popoludnie,
potrebujem vysvetliť jednu vec ohľadom routovania.
Takže v quickstarte je nejaký homepage presenter a ten v šablone
generuje linky:
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
No a mám napísaný takýto routelist:
$router = new RouteList();
$router[] = new Route('<presenter>/<action>/<postId>');
$router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
Všetko funguje, len ja nechápem ako. Problém mám s tým
<postId>. Mám akciu renderShow($postId)
Zistil som, že v route nemôžem napísať <id> ale musí tam byť
<postId>. Nechápem, že prečo. Myslel som, že nezáleží na tom ako sa
parameter volá(však je to maska). Keď predsa volám v php nejakú metódu
s parametrom, tak nezáleží na tom, ako ten parameter pomenujem, v php
záleží na poradí. Nechápem ako to, že Nette sa zaoberá tým ako je ten
parameter v maske pomenovaný.
Môže mi to prosím vás niekto vysvetliť?
Ďakujem.
Editoval Čamo (30. 5. 2014 15:47)
- David Matějka
- Moderator | 6445
ty nazvy parametru v route (to <postId>
) se mapuje na
nazvy parametru v render* nebo action* metodach, tedy na tve
renderShow($postId)
, pokud bys to chtel prejmenovat, musel bys na
obou mistech
- Jan Tvrdík
- Nette guru | 2595
Přečti si dokumentaci. Název masky musí* odpovídat názvu parametru, jinak by nebylo přeci jasné, co je to za parametr, ne?
* Nemusí, jde to přefiltrovat globálními filtry.
- Čamo
- Člen | 798
Nechápem.
Ako a vlastne prečo záleží na tom ako sa ten parameter v metóde volá.
Však na tom vôbec nezáleží. Či záleží???
Potom sa musa všetky parametre v každom presentery a v každej metóde
volať postId. Alebo musím napísať nové pravidlo. Mám pocit, že sa tam
stráca tá univerzálnosť.
Editoval Čamo (30. 5. 2014 16:05)
- David Matějka
- Moderator | 6445
V php obecne zalezi jen na poradi. Ale nette si zjistuje nazvy parametru, abys dostal opravdu to, co chces. Takze jak pojmenujes parametr v presenteru, tak takove jmeno pak musis pouzit i v route
- David Matějka
- Moderator | 6445
No jasne, v route je to zavisle na poradi. Ale proto se tem parametrum davaji nazvy, aby presenter nebyl zavisly na poradi v URL, ale na nazvu parametru
EDIT: nette presenter ani nema tuseni o nejakym poradi v route nebo v url. Jediny, co presenter zajima, jsou nazvy parametru.
Editoval matej21 (30. 5. 2014 16:35)
- Čamo
- Člen | 798
matej21:
Ale presenteru by malo byť tiež jedno, ako sa ten parameter volá. Od jeho
názvu nezávisí vôbec nič. Či čo sa deje?
Však keď v z kódu zavoláš metódu, tak nezáleží ako pomenuješ
parametre $this->renderDefault($ferko_mrkvička). Každý očakáva, že to
bude fungovať. Prečo by v tom mal byť problém?
- David Matějka
- Moderator | 6445
Kazdy ocekava, ze nebude zalezet na poradi parametru, ale pouze na tom, jak
ho pojmenuju.
Predstav si url, ktera ma v query stringu treba:
?foo=1&bar=2
k tomu mam v presenteru
public function renderDefault($foo, $bar)
A melo by to preci fungovat bez ohledu na poradi, tedy i s url
?bar=2&foo=1
Kdyby to bylo jak rikas, tedy dle poradi, dostal bych je obracene.
Jen doplnim, ze pristup k parametrum pomoci parametru render* a action* metod je jen jeden ze zpusobu, take muzes pouzit persistentni parametry
/** @persistent */
public $foo;
nebo si pro parametr „sahnout“:
$this->getParameter('foo');
Vsude zalezi pouze na nazvu parametru.
Ty muzes presenter spustit i „rucne“, ze si vytvoris Nette\Application\Request
se spravnymi parametry. A tuto tridu vyuziva i routovani – vytvori
Request
objekt a preda mu parametry, ktere naslo v url.
EDIT:
metody render* a action*, respektive nazvy jejich parametru, vyuziva i nette
pri vytvareni linku, kdyz neuvedes nazev parametru.
Muzes vytvaret link (v latte):
{link Homepage:default id=>1}
tedy ze uvedes nazev parametru
Pokud vsak nazev neuvedes a pouzijes jen
{link Homepage:default 1}
Tak nette musi ten parametr nejak pojmenovat, aby se vedelo, kam to v URL
patri (dle nazvu parametru) Proto si k tomu najde v HomepagePresenter
odpovidajici action/render metodu a zjisti, ze parametr se jmenuje
$id
…
Editoval matej21 (30. 5. 2014 16:56)
- Čamo
- Člen | 798
Lenže routy sa píšu práve kôli adresám(cool URL), ktoré neprenášajú
názov premennej.
Dostaneš len hodnotu. A pomenuješ ju podľa toho na ktorej pozícii sa v URL
nachádza.
Ja tvrdím, že by malo byť jedno či sa pomenuje id alebo postId. Akurát ma
to obmedzuje v tom, že ja musím tú premennú pomenovať podľa parametra
v metóde.
Keď voláš n:href makro tak nepredávaš názov. Záleží práve na
poradí.
Pri $this->getParameter('foo')
tiež nezáleží na tom ako
sa parameter volá. Ak sa bude volať id, tak budeš volať id, ak postId tak
voláš postId.
Mne len vadí, že na dve rôzne akcie s povedzme jedným parametrom ale inak pomenovaným, musím napísať dve routy ,alebo ich pomenovať rovnako. Mne to príde neefektívne.
- David Matějka
- Moderator | 6445
A pomenuješ ju podľa toho na ktorej pozícii sa v URL nachádza.
No vidis, POJMENUJU. A toto JMENO musim pouzit i v presenteru.
Ja tvrdím, že by malo byť jedno či sa pomenuje id alebo postId.
Ano, je to jedno, jen to jmeno musi byt stejne.
Keď voláš n:href makro tak nepredávaš názov. Záleží práve na poradí.
Viz posledni cast (za editem) v mem prispevku. Tohle je feature pro usnadneni, abys nemusel psat nazvy parametru. Pro urceni nazvu parametru se pak pouziji prave render* nebo action* metody. Ty parametry se tedy taky pojmenuji, jen to nevidis, stara se o to nette.
Nakonec zopakuju: Presenter nezna poradi v URL. V requestu od routeru dostane pouze nazvy parametru a jejich hodnotu. Proto musis pouzivat ty nazvy.
- Jan Tvrdík
- Nette guru | 2595
Čamo: Ještě jednou. Parametr je jednoznačně určen
svým názvem, tak se pozná od ostatních parametrů. Jasné? Jediná výjimka
z tohoto pravidla je, že při tvorbě odkazu pomocí makra link
(plink
, n:href
) nemusíš názvy parametrů uvést a
v tom případě budou určeny na základě názvů parametrů cílové
action*
nebo render*
metody.
Příklady, kde se název parametru může objevit:
- example.com?product=7
- new Route(‚<presenter>/<product>‘)
- public function renderView($product)
- {link Products:view, product ⇒ 7}
- Čamo
- Člen | 798
Ešte posledný pokus:
Povedzme že máme dve rôzne akcie v dvoch presenteroch:
presenter1->renderShow($productId){}
a
presenter2->renderShow($articleId){}
Líšia sa len tým, ako majú pomenované vstupné parametre.
Nette mi dovolí aby som do jednej routy spojil volanie akcie obydvoch presenterov tj.:
<presenter><action> <- platí pre obydva presentery
ale už mi nedovolí, aby som napísal
<presenter><action><id>
musím napísať dve routy miesto jednej.
<presenter><action><productId>
<presenter><action><articleId>
Editoval Čamo (30. 5. 2014 19:33)
- Jan Tvrdík
- Nette guru | 2595
Čamo: Protože to, co chceš, je blbost. Routa
<presenter><action><productId>
podporuje všechny
presentery a přitom pracuje s parametrem konkrétního presenteru. Je to
nesmyslný hybrid mezi obecnou a konkrétní routou. Buď to musíš napsat
zcela obecně <presenter><action><id>
(a pak se
parametr bude jmenovat id) nebo zcela konkrétně
products/<action>/<productId>
a
articles/<action>/<articleId>
.
- Čamo
- Člen | 798
Jan Tvrdík:
Dokumentácia citujem: „Pamatujte na to, že počet rout má vliv na rychlost
aplikace, zejména při generování odkazů.“
O toto mi ide, nie o to či je to podľa teba sémantická blbosť alebo
nesmyslný hybrid.
EDIT:
A ten hybrid som takto nenapísal ja, ale je to okopírované z quickstartu.
Tak sa trochu schlaď.
Editoval Čamo (30. 5. 2014 19:59)
- Jan Tvrdík
- Nette guru | 2595
Čamo: Výkon je podřadný funkčnosti. Je docela jedno, že to bude rychlé, když to nebude vůbec fungovat.
A ten hybrid som takto nenapísal ja, ale je to okopírované z quickstartu.
Můžeš odkázat konkrétně? Prošel jsem český i anglický QS a uvedený kód jsem nikde neviděl.
- Čamo
- Člen | 798
https://doc.nette.org/…eating-posts
https://doc.nette.org/…/single-post
Pardón:
https://doc.nette.org/…eating-posts#…
https://doc.nette.org/…/single-post#…
Editoval Čamo (30. 5. 2014 20:38)
- Jan Tvrdík
- Nette guru | 2595
Nikde nevidím, že by tam používali výše uvedenou hybridní, nesmyslnou
a prakticky nefunkční routu. Používat pro parametry názvy jako
postId
je zcela v pořádku. Ale musí se pro to pochopitelně
napsat správné routy, např.
new Route('posts/<action>[/<postId>]', array(
'presenter' => 'Posts',
));
- mystik
- Člen | 312
Čamo: Zkus se zamyslet jak by to fungovalo, kdyby ten parametr nebyl jeden, ale bylo jich třeba pět a některé nepovinné. Nebo případ, kdy by jsi chtěl do budoucna změnit pořadí parametrů v URL. Nebo jsi měl pro jeden presenter více rout. Pak už se bez pojmenování obejdeš jen těžko.