Routing – platnost stylu pro konkrétní presenter

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
lucass
Člen | 89
+
0
-

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

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

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)

David Grudl
Nette Core | 8218
+
0
-

Takto zadanou routou projde skutečně jen Cms:document, nic jiného.

lucass
Člen | 89
+
0
-

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)

pmg
Člen | 372
+
0
-

Nejspíš jsem narazil na stejný problém. Chtěl jsem vytvořit návod, jak si v presenteru zvolit routu pro generování odkazů. Dříve jsem se na to ptal, ale teď se mi to nepodařilo zprovoznit.

David Grudl
Nette Core | 8218
+
0
-

Mám dvě routy:

  1. /<lang>/<xxxx>
  2. /<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
+
0
-

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

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

David Grudl napsal(a):

Mám dvě routy:

  1. /<lang>/<xxxx>
  2. /<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)

Jod
Člen | 701
+
0
-

Ešte si môžeš napísať vlastný router =)

PetrP
Člen | 587
+
0
-

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

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

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

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

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

Doporučuji použít vlastní router, k inspiraci bude stačit vynikající recept a trocha koření =)

PetrP
Člen | 587
+
0
-

_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.