Routing – platnost stylu pro konkrétní presenter
- lucass
- Člen | 89
Zdravíčko,
měl bych dotaz ohledně routování, resp. stylů v překladovém slovníku. Potřeboval bych mít routu s překladem platnou pouze pro konkrétní presenter. Mám na mysli něco ve stylu IDčka v CSS, tj.:
<?php
$router[] = new Route('<lang '.$lang.'>/<presenter Cms#cs-presenter>/', array(
'presenter' => 'Cms',
'action' => 'document',
));
?>
Důvodem je, aby tímto procházely jen ty odkazy, jejichž presenter je Cms, ale další pochroupnula až další routa. Pokud se to takto nepíše, nebo pokud to nejde, existuje jiný způsob (např. regulární výrazy)?
Díky.
Editoval lucass (11. 2. 2009 19:57)
- David Grudl
- Nette Core | 8218
Záměru moc nerozumím, respektive co by se mělo překládat? Pokud tím má procházet jen jeden presenter, tak bych ho jako parametr v masce vůbec neuváděl.
- lucass
- Člen | 89
Když to napíšu pseudokódem:
if (presenter == Cms && action == document) then pouzij_prepis_a_prekad_dle_teto_masky.
Tzn. aby když mi přijde např. presenter Product s nějakou action list, tak aby to tuto routu ignorovalo. Jestli už si rozumíme…
Ještě jeden příklad:
<?php
$router[] = new Route('<lang '.$lang.'>/<catId>/', array(
'presenter' => 'Cms',
'action' => 'document',
'catId' => 0
));
?>
Jedná se mi o to, že chci, aby tato routa fungovala jen a pouze pro presenter Cms a action document. Je možné toho docílit? Tj. nechci, aby Product::detail(2) touto routou prošel.
Editoval lucass (12. 2. 2009 11:53)
- lucass
- Člen | 89
Bohužel tomu tak není. Mám URL /cs/sitemap/, kde Sitemap je presenter, nikoliv catId, a přesto mi to tedy požere výše zmíněná routa. Uvádím výpis s RoutingDebuggeru:
► Cms:document
Parameter Value
lang cs
catId sitemap
action document
Routa, která to požere:
yes Route <lang cs>/<catId>/ presenter = Cms, action = document, catId = 0
Ač by to měla být tato:
may Route <lang cs>/<presenter #cs-presenter>/<action #cs-action>/<catId>/<objectId>/ presenter = Default, action = default, catId = NULL, objectId = NULL
Pokud obrátím pořadí rout, tak mi to samozřejmě vezme správně, ale pro zase nefugunje routa pro Cms::document, jelikož je požrána touto obecnou routou.
Revize Nette 210.
Editoval lucass (13. 2. 2009 9:53)
- David Grudl
- Nette Core | 8218
Mám dvě routy:
- /<lang>/<xxxx>
- /<lang>/<yyyy>
a url /cs/sitemap/
. Do které routy to padne? Do první. Jak by
bylo možné rozlišit, že to má padnout do druhé, když jsou obě naprosto
stejné?
Dejme tomu, že první routa je platná pouze pro konkrétní presenter. Mění se tím něco pro rozlišení, do které routy url `/cs/sitemap/ padne? Asi ne, protože jsou stále obě stejné.
Takže nejprve si sám zodpověz otázku, kdy má url /cs/neco
padnout do první a kdy do druhou routy. Když budeš mít jasnou odpověď,
můžeš ji formálně zapsat pomocí rout.
- pmg
- Člen | 372
Mně šlo jen o generování odkazů.
$router[] = new Route('first-route/<presenter>/<view>', array(
'route' => 0,
));
$router[] = new Route('second-route/<presenter>/<view>', array(
'route' => 1,
));
Parametr route v masce není obsažen. Očekával bych, že když
v presenteru vytvořím odkaz s parametrem route=1
, použije se
pro něj druhá routa. Ale zdá se, že ne, i když jsem měl pocit, že to tak
dříve fungovalo.
- pmg
- Člen | 372
Omlouvám se, překlep' jsem se při volání. Funguje to správně.
Abyste se mohli z mojí chyby poučit, budete si ji muset najít v následujícím kódu. Napovím, že bych se jí nedopustil, kdybych používal IDE.
class HomepagePresenter extends BasePresenter
{
/* @persistent */
public $route = 2;
public function renderDefault($route)
{
$this->template->route = $route;
}
}
Řešení: ?
- lucass
- Člen | 89
David Grudl napsal(a):
Mám dvě routy:
- /<lang>/<xxxx>
- /<lang>/<yyyy>
a url
/cs/sitemap/
. Do které routy to padne? Do první. Jak by bylo možné rozlišit, že to má padnout do druhé, když jsou obě naprosto stejné?Dejme tomu, že první routa je platná pouze pro konkrétní presenter. Mění se tím něco pro rozlišení, do které routy url `/cs/sitemap/ padne? Asi ne, protože jsou stále obě stejné.
Takže nejprve si sám zodpověz otázku, kdy má url
/cs/neco
padnout do první a kdy do druhou routy. Když budeš mít jasnou odpověď, můžeš ji formálně zapsat pomocí rout.
Tou odpovědí může být to, co jsem psal v prvním příspěvku ze dne 11. 2. 2009 19:57, event. 12. 2. 2009 11:29. To je to, jak rozlišit, aby to padlo do té či oné routy, tj. definovat striktně, že jen pro tento presenter a tuto action využij tuto routu, jinak běž dál.
Jinak ty routy přece nejsou stejné. Jedna má za langem catId, druhá za langem presenter. Takže by neměl název presenteru padnout do routy místo catId. A nebo mi pořád unikají souvislosti.
Editoval lucass (16. 2. 2009 9:24)
- PetrP
- Člen | 587
lucass napsal(a):
Jinak ty routy přece nejsou stejné. Jedna má za langem catId, druhá za langem presenter. Takže by neměl název presenteru padnout do routy místo catId. A nebo mi pořád unikají souvislosti.
V /cs/Xyz
je Xyz presenter nebo catId? A jak to má router
poznat?
Tou odpovědí může být to, co jsem psal v prvním příspěvku ze dne 11. 2. 2009 19:57, event. 12. 2. 2009 11:29.
Možná by se hodilo napsat obě routy přesně tak jak je máš. A napsat pár příkladů kdy by něco mělo projít první a kdy druhou. Možná pak pochopíme o co ti přesně jde a řeknem jak to udělat.
To je to, jak rozlišit, aby to padlo do té či oné routy, tj. definovat striktně, že jen pro tento presenter a tuto action využij tuto routu, jinak běž dál.
Ono je to obraceně podle routy se vybírá presenter než že by se podle presenteru vybírala routa.
- lucass
- Člen | 89
Tak jsem to zřejmě špatně chápal. Já měl za to, že dle toho pole, např.
<?php
array(
'presenter' => 'Cms',
'action' => 'document',
'catId' => 0
);
?>
to pak teprve přepisuje na masku dle té routy. Teď mi dochází, že je to asi nemožné, když mu vnitřně přijde jen URL v nějakém tvaru a on by nepochopil, na co to má přepsat, tj. co je na jaké pozici.
Prostě jsem to celou dobu chápal tak, že zpětný překlad z URL na nějakou controlling akci probíhá takto:
if (presenter == Cms && action == document) then pouzij_prepis_a_prekad_dle_teto_masky
Kdežto toto je podmínka jen pro případ přepisu odkazů na URL, kdežto z URL to funguje přesně obráceně:
if (sedi_maska) then do_pole_s_parametry_napasuj_hodnoty_dle_masky
Je to tak?
Editoval lucass (16. 2. 2009 13:57)
- lucass
- Člen | 89
Jinak konkrétní příklad:
URL: /cs/cms/documents/obecne-dokumenty/
cs – lang,
cms – presenter,
documents – action,
obecne-dokumenty – catId,
Ta URL je ošklivá, chtěl jsem docílit tohoto:
URL: /cs/obecne-dokumenty/
Tj. aby implicitně on pokaždé, když mu přijde jen /lang/catId vzal Cms presenter a action documents.
Problémem je, že toto funguje v případě, že takovou routu umístím před obecnou routu, která zpracovává vše ostatní, ale prochází touto routou na /lang/catId i třeba odkaz, který je ve tvaru /lang/presenter. Což je chyba. Jestli si už rozumíme…
Editoval lucass (16. 2. 2009 14:04)
- kravčo
- Člen | 721
lucass napsal(a):
Jinak konkrétní příklad:
URL:
/cs/cms/documents/obecne-dokumenty/
cs – lang,
cms – presenter,
documents – action,
obecne-dokumenty – catId,Ta URL je ošklivá, chtěl jsem docílit tohoto:
URL:
/cs/obecne-dokumenty/
Tj. aby implicitně on pokaždé, když mu přijde jen /lang/catId vzal Cms presenter a action documents.
Problémem je, že toto funguje v případě, že takovou routu umístím před obecnou routu, která zpracovává vše ostatní, ale prochází touto routou na /lang/catId i třeba odkaz, který je ve tvaru /lang/presenter. Což je chyba. Jestli si už rozumíme…
Ako píše PetrP, router nevie, ktorý prezenter bude výsledkom routovania
(jeho práca je ho určiť), nevie sa preto podľa toho rozhodovať, ktorú
routu použiť. Použije prvú, ktorá vyhovuje pre URL a podľa nej vráti
internú požiadavku (PresenterRequest
).
Ono pole s parametrami slúži na to, aby bolo možné nastaviť parametre, ktoré sa v maske neobjavia a tiež defaultné hodnoty.
Situácia by sa napríklad značne zjednodušila v prípade, že
catId
by bolo číselné… rozhodovalo by sa podľa
tvaru URL.
V tvojom prípade to rozlíšiť nejde, riešením by bola iná (odlíšiteľná) routa, ktorá by bola jednoduchšia. Skús sa inšpirovať Davidovími routami
- PetrP
- Člen | 587
lucass napsal(a):
Jinak konkrétní příklad:
URL:
/cs/cms/documents/obecne-dokumenty/
cs – lang,
cms – presenter,
documents – action,
obecne-dokumenty – catId,Ta URL je ošklivá, chtěl jsem docílit tohoto:
URL:
/cs/obecne-dokumenty/
Tj. aby implicitně on pokaždé, když mu přijde jen /lang/catId vzal Cms presenter a action documents.
Problémem je, že toto funguje v případě, že takovou routu umístím před obecnou routu, která zpracovává vše ostatní, ale prochází touto routou na /lang/catId i třeba odkaz, který je ve tvaru /lang/presenter. Což je chyba. Jestli si už rozumíme…
Tak bud zkusit něco takového, v případě, že by to šlo:
$router[] = new Route('<lang '.$lang.'>/<presenter>/<action>/<catId>/', array(
'catId' => 0
));
$router[] = new Route('<lang '.$lang.'>/<catId>/', array(
'presenter' => 'Cms',
'action' => 'document',
'catId' => 0
));
nebo si zkusit zahrát z Překladovým slovníkem:
Route::setStyleProperty('catId', Route::FILTER_IN, 'styleProperty_Cms_document');
function styleProperty_Cms_document($s)
{
// poznat jestli je catId v Cms::document
// zaexperimentovat co se musí vrátit, aby se přešlo na další routu
}
$router[] = new Route('<lang '.$lang.'>/<catId>/', array(
'presenter' => 'Cms',
'action' => 'document',
'catId' => 0
));
// nezkoušel jsem to, ale doufám, že to funguje tak jak myslím
nebo si proste napsat svojí vlastní jednoduchou routu.
- _Martin_
- Generous Backer | 679
Doporučuji použít vlastní router, k inspiraci bude stačit vynikající recept a trocha koření =)
- PetrP
- Člen | 587
_Martin_ napsal(a):
Doporučuji použít vlastní router, k inspiraci bude stačit vynikající recept a trocha koření =)
PetrP napsal(a):
nebo si proste napsat svojí vlastní jednoduchou routu.
Tímto jsem právě myslel vytvořit si vlastní router.