[2009–09–24] Route: volitelné sekvence […]
- David Grudl
- Nette Core | 8199
V routovací masce třídy Route lze označovat tzv. volitelné sekvence. Ty
se uzavírají do složených hranatých závorek. Ukažme si to na
jednoduchém příkladu:
$route = new Route('[<lang [a-z]{2}>/]<name>', array());
Akceptuje cesty:
/cs/download => lang=cs, name=download
/download => lang=NULL, name=download
Výhodou je, že volitelný parameter se může nacházet i uprostřed masky, ale především lze definovat jeho okolí, v tomto případě znak lomítka, které musí parametr, pokud je uveden, obklopovat. To lze využít například u volitelných subdomén:
$router[] = new Route('//[<module>.]example.com/<presenter>/<action>', array(
'presenter' => 'Homepage',
'action' => 'default',
));
Závorky je možné libovolně zanořovat:
$route = new Route('[<lang [a-z]{2}>[-<sublang>]/]<name>[/page-<page>]', array(
'page' => 0,
));
Akceptuje cesty:
/cs/stranka
/en-us/stranka
/stranka
/stranka/page-12
Přitom uvnitř volitelné sekvence nemusí být ani žádný parametr:
$route = new Route('index[.html]', array());
Akceptuje cesty:
/index.html
/index
Generuje:
/index
Generování URL
Při generování cest se používá pravidlo nejkratšího
URL, takže všechno, co lze vynechat, se vynechá. Právě proto routa
index[.html]
generuje, jak jsem naznačil výše, cestu
index
.
Pokud byste naopak chtěli generování volitelné sekvence vynutit, napište za levou závorku vykřičník:
$route = new Route('index[!.html]', array());
Akceptuje cesty:
/index.html
/index
Generuje:
/index.html
Opět lze libovolně kombinovat společně se zanořováním a parametry.
Interní poznámka: volitelné parametry (tj. parametry mající výchozí hodnotu) mimo složených závorek se chovají v podstatě tak, jako by byly uzávorkovány následujícím způsobem:
// tento zápis
$route = new Route('<presenter>/<action>/<id>', array(
'presenter' => 'Dashboard',
'action' => 'default',
'id' => NULL,
));
// odpovídá funkčně tomuto:
$route = new Route('{<presenter>/{<action>/{<id>}}}', array(
'presenter' => 'Dashboard',
'action' => 'default',
// 'id' => NULL, neni potřeba uvádět
));
Pokud byste chtěli ovlivnit chování zpětných lomítek, tj. aby se místo
např. dashboard/view/
generovalo dashboard/view
, lze
toho docílit takto:
$route = new Route('{<presenter>{/<action>{/<id>}}}', array(
'presenter' => 'Dashboard',
'action' => 'default',
));
Což ale není z logiky URL-tvorby správné.
Foo-parametery
Ačkoliv možnosti foo-parametrů a volitelných sekvencí se trošku překrývají, navzájem se nenahrazují. Účelem foo-parametrů je dostat do masky regulární výrazy, naopak volitelné sekvence s nimi vůbec nepracují.
- Ondřej Mirtes
- Člen | 1536
Jak by tedy vypada správná tvorba URL, pokud bych tam ty konečná lomítka nechtěl?
Při routě <presenter>/<action>/<id>
mi
vzniká URL presenter/action/5
a pokud je <id>
nepovinný, tak vznikne presenter/action/
, takže podoba odkazů
není jednotná. Vyřešil jsem to tak, že jsem začal používat i konečná
lomítka, ale nelíbí se mi.
Nechtěl bys přidat třeba něco takovéhleho? :)
Route::endSlashes = false;
…abychom nemuseli u každé routy (z tohoto důvodu) manipulovat s těmi složenými závorkami, které IMHO hezký zápis rout docela znepřehledňují?
Editoval LastHunter (24. 9. 2009 22:10)
- David Grudl
- Nette Core | 8199
Nechtěl, protože si myslím, že to není správné. Nekonzistentně by
totiž presenter/action
jednou vystupoval v roli souboru a jednou
v roli adresáře.
- Honza Marek
- Člen | 1664
Já to třeba většinou mám tak, že v některých presenterech mám jedinou action default. Logicky by tedy jméno presenteru mělo „vystupovat v roli souboru“. Jindy je tam těch actionů víc, tedy dochází k nejednotnosti.
Taky bych tedy uvítal, abych mohl nastavit, že na konci lomítka nebudou.
- _Martin_
- Generous Backer | 679
LastHunter napsal(a):
Nechtěl bys přidat třeba něco takovéhleho? :)
Route::endSlashes = false;
Vzhledem k tomu, co routy nyní dokáží, by toto bylo značně nesystémové řešení. Doporučuji (když to musí být) použít příklad, který uvedl David – ať se tu vyhneme diskuzi o tom, jestli je lepší lomítka na konci mít či nikoliv.
- Jod
- Člen | 701
Neviem či robím niečo zle, ale toto mi nefunguje:
<?php
$router[] = new Route('//[<module>.]example.com/<presenter>/<action>/<id>', array(
'module' => 'Www',
'presenter' => 'Homepage',
'action' => 'default',
'id' => null,
));
?>
Dáva mi to takéto: No route for Login:Homepage:default()
Keď pridám do presentera public $autoCanonicalize = false; tak mi to nechce
robiť linky. {link :Login:Homepage:} dáva mriežku.
Editoval Jod (7. 10. 2009 0:28)
- Petr Motejlek
- Člen | 293
Tohle je velmi hezké, hlavně to „okolí“ jako je tečka/lomítko. Ještě k té diskuzi o pohledech – osobně taky nevidím moc využití v tom, že je jeden Presenter a ten má několik View. Zatím jsem ještě nenarazil na případ, kdybych si skutečně řekl „Ano, to je přesně to, kde chci použít víc pohledů!“. Vždycky mi přišlo, že když bych do toho chtěl vnést nový pohled, tak je to nový Presenter ;).