[2008-12-02] Překladový slovník pro Route

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

Pokud píšete aplikaci v angličtině (tj. neprasíte českoangličtinu jako Rudolf Pecinovský) a web má běžet v českém prostředí, tak vám nemusí dostačovat jednoduché routování typu:

$router[] = new Route('<presenter>/<action>/<id>', array(
	'presenter' => 'Homepage',
	'action' => 'default',
	'id' => NULL,
));

A to z důvodu, že presentery Product, Basket, Customer chcete mít v URL reprezentované jako produkt, kosik, zakaznik. Věc je možno řešit buď vytvořením více rout (což však bude zpomalovat aplikaci), nebo definicí vlastních filtračních funkcí:

Route::setStyleProperty('presenter', Route::FILTER_IN, 'myFunctionIn');
Route::setStyleProperty('presenter', Route::FILTER_OUT, 'myFunctionOut');

function myFunctionIn($s) {
	return ...;
}

function myFunctionOut($s) {
	return ...;
}

Což je zase poměrně komplikované. Třída Route proto nově nabízí možnost nastavit překladovou tabulku:

Route::setStyleProperty('presenter', Route::FILTER_TABLE, array(
        'produkt' => 'Product',
        'kosik' => 'Basket',
        'zakaznik' => 'Customer',
));

Tabulku tvoří páry „řetězec v URL“ ⇒ „presenter“.

Zajímavost: jeden presenter může být uveden pod více ruznými kliči. Pak k němu povedou všechny varianty (tedy vytvoří se aliasy), s tím, že za kanonickou se považuje ta poslední.

Jod
Člen | 701
+
0
-

Úplná paráda, díky, onedlho som to plánoval riešiť.

romansklenar
Člen | 655
+
0
-

Připojuju se k ovacím – luxus nad luxus ;)

lucass
Člen | 89
+
0
-

Zdravím všechny,

překladový slovník je výborná věc, avšak bych potřeboval použít nejen jeden, ale více těchto, a to na základě jazyka, který mi přišel v URL. Nějak jsem nepřišel na to, jak v boostrapu zjistit lang z GETu. Zkoušel jsem přes Environment vrátit HttpRequest a nad ním volat getQuery(‚lang‘), ale je NULL. Vrátí mi jen ty parametry, které nejsou v routě, tj. jsou za otazníkem. Proměnnou $lang mám jako perzistentní v BasePresenteru.

V systému mám jedinou routu definovanou takto:

$router[] = new Route('<lang>/<presenter>/<action>/<name>', array(
					'lang' => Environment::getConfig('variable')->defaultLang,
					'presenter' => 'Default',
					'action' => 'default',
					'name' => NULL
));

Důvod, proč chci na základě jazyka používat různé slovníky, je následující, např.:

/cs/produkty/outwet-lp1
/en/products/outwet-lp1
...

Prozatím jsem to řešil více routami, kde jsem lang napevno nastavoval, ale jednodušší by to bylo, myslím, pomocí těch slovníků.

Díky za každou radu.

Dodatek: Pokud neroutuji, tak si lang v pořádku přes zmíněný HttpRequest vrátím. Jinak verze a revize je poslední, tj. 0.8, rev. 139.

Editoval lucass (4. 12. 2008 14:54)

Ola
Člen | 385
+
0
-

Co třeba takhle (když máš uloženej jazyk v $lang)?

<?php
if ($lang == 'cs')
{
	Route::setStyleProperty('presenter', Route::FILTER_TABLE, array(
        	'produkty' => 'Product',
	));
}
else if ($lang == 'en')
{
	// zde by němělo být třeba nic dělat, pokud máš názvy presenterů shodný s adresou
	Route::setStyleProperty('presenter', Route::FILTER_TABLE, array(
        	'products' => 'Product',
	));
}
 // spousta dalších jazyků

Editoval Ola (4. 12. 2008 15:41)

lucass
Člen | 89
+
0
-

Ola napsal(a):

Co třeba takhle (když máš uloženej jazyk v $lang)?

<?php
if ($lang == 'cs')
{
	Route::setStyleProperty('presenter', Route::FILTER_TABLE, array(
        	'produkty' => 'Product',
	));
}
else if ($lang == 'en')
{
	// zde by němělo být třeba nic dělat, pokud máš názvy presenterů shodný s adresou
	Route::setStyleProperty('presenter', Route::FILTER_TABLE, array(
        	'products' => 'Product',
	));
}
 // spousta dalších jazyků

V tomto jsme si nerozuměli:) Přesně o to mi sice jde, ta myšlenka je jasná, ale $lang je perzistentní a navíc je to proměnná prezenteru, kdežto já ty routy i slovník dělám v bootstrapu, takže na $lang nevidím. Jde mi tedy v podstatě jen o to, jak dostat $_GET[„lang“] v bootstrapu při použití routy, kde v routě je <lang>.

Editoval lucass (4. 12. 2008 15:49)

David Grudl
Nette Core | 8082
+
0
-

getQuery() vrací parametry za otazníkem, ty potřebuješ jazyk vytáhnout z URL, to vrací metoda getUri() a část path.

Druhou možností je definovat nové třídy a jim přiřadit slovníky:

// vytvoří "třídu" cs-presenter jako kopii presenter
Route:addStyle('#cs-presenter', 'presenter');

// nastavíme slovník třídě
Route::setStyleProperty('cs-presenter', Route::FILTER_TABLE, array(
	'produkty' => 'Product',
));

// v routě uvedeme, aby se parametr řídil podle nové třídy
$route = new Route('<presenter #cs-presenter>/<id>', ...);
lucass
Člen | 89
+
0
-

Metodu getUri() a path jsem už také zkoušel, ale to mi vrátí již v clean tvaru, nikoliv v query stringu nebo ještě lépe v polim, tudíž bych to musel ručně parsovat. Takže zkusím spíš tu druhou možnost s novými třídami, i když mi zcela není jasné, jak pozná, že byl zvolen ten či onen jazyk…

Díky.

lucass
Člen | 89
+
0
-

Zdravím,

konečně jsem se dostal k vyzkoušení těch tříd. Omlouvám se za opětovný dotaz, ale trochu se v tom ztrácím. Zkusil jsem si nadefinovat třídu #cs-presenter a třídu #en-presenter:

Route::addStyle('#en-presenter', 'presenter');
Route::addStyle('#cs-presenter', 'presenter');

Route::setStyleProperty('#cs-presenter', Route::FILTER_TABLE, array(
	'produkty' => 'Products',
	'kontakty' => 'Contacts',
));

Route::setStyleProperty('#en-presenter', Route::FILTER_TABLE, array(
	'products' => 'Products',
	'contacts' => 'Contacts',
));

Pak mám routu:

$router[] = new Route('<lang>/<presenter #cs-presenter>/<action>/<name>', array(
					'lang' => Environment::getConfig('variable')->defaultLang,
					'presenter' => 'Default',
					'action' => 'default',
					'name' => NULL
));

Tady ale potřebuji nastavit třídu presenteru dle aktuálního jazyka, tj. mít něco jako

$router[] = new Route('<lang>/<presenter #{$_GET['lang']}-presenter>/<action>/<name>', array(
					'lang' => Environment::getConfig('variable')->defaultLang,
					'presenter' => 'Default',
					'action' => 'default',
					'name' => NULL
));

Jak psal David v předchozím příspěvku ze 4. 12. 2008 16:34, URL vrací getUri() a část path. Jenže path se mi vrátí jako string ve tvaru /cs/produkty/, takže nezbyde nic jiného, než to parsovat ručně a doufat, že první bude vždy lang. Neexistuje něco jako pathAsArray, kde bych měl path v asociativním poli, tj. abych to mohl používat podobně jako $_GET?

Jednoduše řečeno: potřebuji v boostrapu zjistit aktuální jazyk z URL (přechroupáno přes routy) a dle něj nadefinovat příslušný slovník, resp. třídu. Při použití $_GETu (což není pěkné) v něm mám stejně jen atributy URL, které jsou za otazníkem, tj. které nezpracuje žádná routa.

David Grudl
Nette Core | 8082
+
0
-

Není jednodušší napsat přímo

$router[] = new Route('cs/<presenter #cs-presenter>/<action>/<name>', array(
	'lang' => 'cs',
	'presenter' => 'Default',
	'action' => 'default',
	'name' => NULL
));

$router[] = new Route('en/<presenter #en-presenter>/<action>/<name>', array(
	'lang' => 'en',
	'presenter' => 'Default',
	'action' => 'default',
	'name' => NULL
));
lucass
Člen | 89
+
0
-

Asi je:) Takto jsem to měl původně do chvíle, než se tu objevila novinka s překladovým slovníkem. Chtěl jsem to tedy využít i nějak dynamicky, abych nepřidával routy, které pro danou jazykovou mutaci nejsou potřeba. Vrátím to tedy zpět a slovníky využiju jen k překladu presenteru a view.

Díky.

LM
Člen | 206
+
0
-

Proč nejde na query parametry použít FILTER_IN nebo FILTER_TABLE? (FILTER_OUT zdá se funguje)

David Grudl
Nette Core | 8082
+
0
-

Máš pravdu, že FILTER_OUT se může použít na query parametry, což je spíš chyba. Nenapadlo mě, že by bylo užitečné filtrovat query parametry.

LM
Člen | 206
+
0
-

Asi jsem divnej :-) ale vadí mi že bych měl url ve tvaru: o-vas?akce=Page:Edit namísto pěknějšího o-vas?akce=editovat nebo o-vas?action=Edit (což se dá obejít přes nastavení module routě), o-vas/editace nejde použít, id stránky může obsahovat i znak /, jako na nette/dibi/texy Wiki.

David Grudl
Nette Core | 8082
+
0
-

Strašně nerad něco upravuju ve třídě Route, jenom pochopit jak to pracuje mi zabere pár hodin… Ale je to tam.

LM
Člen | 206
+
0
-

Díky! Funguje to bezvadně.