[2008-12-02] Překladový slovník pro Route
- David Grudl
- Nette Core | 8218
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í.
- lucass
- Člen | 89
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
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
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 | 8218
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
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
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 | 8218
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
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.
- David Grudl
- Nette Core | 8218
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
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 | 8218
Strašně nerad něco upravuju ve třídě Route, jenom pochopit jak to pracuje mi zabere pár hodin… Ale je to tam.