[2009–09–24] Route: volitelné sekvence […]

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8199
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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)

David Grudl
Nette Core | 8199
+
0
-

Můžeš to vyzkoušet v aktuální verzi?

Jod
Člen | 701
+
0
-

Už som to poriešil, bol tam niekde malý problémik s parametrom dosť skrytý :) Potom mi to začalo generovať url.

amsys
Člen | 20
+
0
-

Skvělé! díky

Petr Motejlek
Člen | 293
+
0
-

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 ;).