Jazyk jako GET parametr a odebrani z URL
- hurvajs
- Člen | 86
Zdravím, přepínání jazyků jsem měl už vyřešené, ale zákazník
přišel s tím, že nechce URL ve tvaru http://admin/
a ne
http://cs/admin/
s tím, že si může kdykoliv vybrat jazyk. Ten
se pak předá přes GET. Přepínání mi funguje, ale chtěl bych se zeptat,
jestli jde nějak GET parametr „vyndat“. Raději uvedu příklad:
Admin v
* češtině: http://admin/?lang=cs
nebo
http://admin/
* angličtině: http://admin/?lang=en
Jednoduše mi jde o to, aby v HTML kódu byly URL generovány ve tvaru
http://admin/?lang=cs
, ale aby router takovou adresu zachytil, ale
vygeneroval URL jen ve tvaru http://admin/
s tím, že lang
si uloží do persistentniho parametru.
Je mi jasné, že by to šlo řešit napsaním vlastního routeru, kde si to upravím jak potřebuji. Jen se mi to zdá zbytěčné.
Momentálně to mám takto (zatím jen zjednodušená verze)
<?php
if (function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) {
Route::addStyle('?lang', null);
Route::setStyleProperty('?lang', Route::PATTERN, '[a-z]{1,3}');
Route::setStyleProperty('?lang', Route::FILTER_OUT, 'getLangNameById');
Route::setStyleProperty('?lang', Route::FILTER_IN, 'getLangIdByName');
$router[] = new Route('admin/<presenter>/<action>/<id> ? <lang>', array(
'module' => 'Backend',
'presenter' => 'Default',
'action' => 'default',
'id' => null,
'lang' => null
));
} else {
$router[] = new SimpleRouter('Frontend:Homepage:show');
}
function getLangNameById($s)
{
return $s == 'cs' ? null : 'en';
}
function getLangIdByName($s)
{
return $s == 'cs' ? null: 'en';
}
?>
- Toto funguje pouze za předpokladu, že dostanu url ve tvaru
http://admin/
http://admin/?lang=en
- Selže na
http://admin/?lang=cs
– což je samozřejmě pochopitelné, protože místo ‚cs‘ vracím ‚null‘.
- _Martin_
- Generous Backer | 679
Jestli ti dobře rozumím, tak akorát ten parametr lang vyndej z tvaru URL
(čili <lang>
pryč) a nech mu výchozí hodnotu na cs. Potom
jej Nette bude předávat jako standardní parametr za otazníkem.
A v případě, že se bude rovnat cs, tak převede na kanonickou URL bez toho
parametru.
- hurvajs
- Člen | 86
No uplne presne je mym cilem to, aby Nette reflektovalo nastaveni jakyka, ale
nezobrazovalo mi ho v URL prohlizece. Ci-li abych v URL mel
treba /admin/user/list/
, ale v HTML byly vygenerovany s
lang
⇒ /admin/user/list/?lang=cs
. S tim, ze se
?lang
ulozi treba do $_SERVER
.
Doufam, ze je to srozumitelne.
To _martin_: pripadne mohu poskytnout ICQ a muzeme to probrat… ;-)
Editoval hurvajs (15. 11. 2009 16:44)
- _Martin_
- Generous Backer | 679
hurvajs napsal(a):
No uplne presne je mym cilem to, aby Nette reflektovalo nastaveni jakyka, ale nezobrazovalo mi ho v URL prohlizece. Ci-li abych v URL mel treba
/admin/user/list/
, ale v HTML byly vygenerovany slang
⇒/admin/user/list/?lang=cs
. S tim, ze se?lang
ulozi treba do$_SERVER
.Doufam, ze je to srozumitelne.
To _martin_: pripadne mohu poskytnout ICQ a muzeme to probrat… ;-)
No, asi tak: pokud chceš reflektovat nějaký stav aplikace a ten stav nemá být zohledněn v URL, pak (vzhledem k tomu, že protokol HTTP je bezstavový) nezbývá, než si jej uložit někam jinam – třeba do session.
Můj názor sice je, že zrovna jazyk by měl být v URL zohledněn, ovšem tvého klienta asi těžko přesvědčím…
Proti ICQ bych se nebránil, ale když to řešíme tady, tak má víc uživatelů šanci, že na to narazí při řešení svého problému.
- hurvajs
- Člen | 86
Jasne, to chápu, že musím někam tu proměnnou uložit, abych si pamatoval její nastavení. Rozdodně odmítám cookies.
Mě by v podstatě stačilo, říct nějak MultiRouteru
, aby
při překládání URL nepoužil ?lang=cs
. Protože, jestli chápu
dobře router, tak se nejprve zjistí jestli daná URL odpovídá masce routeru
(match()
) a pak se dál v aplikaci volá
(constructUrl()
).
Ted pro gettext nastavuji přes putenv()
proměnnou s jazykem,
na základě ní pak nastavím gettext. Zkoušel jsem i unsetnout parametr
lang, ale nic nezabralo.
_Martin_ napsal(a):
Můj názor sice je, že zrovna jazyk by měl být v URL zohledněn, ovšem tvého klienta asi těžko přesvědčím…
Tak to je i můj názor. Proto jsem měl původně URL ve tvaru
http://cs/admin/
. Bohužel to tak zákazník chce a stojí si na
tom, že to chce ukládat max. do serverového prostředí.
Jinak to s tim ICQ, jsem myslel, tak že by to bylo rychlejší, nemám problém to řešit zde a bude to jak, píšeš přínosem i pro jiné.
- _Martin_
- Generous Backer | 679
No, když to nemá být v URL, tak to nesmí být ani v routeru.
A pakliže (jestli to dobře chápu) máš ten jazyk v URL kvůli
přepínání mezi jazyky, tak bude lepším řešením použít signál.
Samotný lang
do routeru vůbec nedávej. A to, že defaultně
bude čeština, nastav logikou, která si to ukládá (třeba do té
SESSION – neni klíč v SESSION, nastaví ho na cs).
- hurvajs
- Člen | 86
_Martin_ napsal(a):
No, když to nemá být v URL, tak to nesmí být ani v routeru. A pakliže (jestli to dobře chápu) máš ten jazyk v URL kvůli přepínání mezi jazyky, tak bude lepším řešením použít signál. Samotný
lang
do routeru vůbec nedávej. A to, že defaultně bude čeština, nastav logikou, která si to ukládá (třeba do té SESSION – neni klíč v SESSION, nastaví ho na cs).
To jsem si myslel, že to nesmí být ani routeru. Řešení pomocí signálu mě nenapadlo, ještě jsem to neřešil. Takže musím nastudovat signály. Předpokládám, že to bude v dokumentaci, ale neměl bys nějaké malé rychlé how to? ;-)
Ten session je opravdu jediné řešení, protože pokud nemohu použít cookies, tak to není kam uložit, tak abych měl informaci i pro další stránky.
- lucass
- Člen | 89
Třeba do BasePresenteru si dej handleChangeLang() s parametrem $lang.
<?php
...
public function handleChangeLang($lang) {
$sess = Environment::getSession('project');
$sess->lang = $lang;
}
...
?>
Defaultně, třeba při startupu, si tu session získej a zjisti aktuální nastavení jazyka, a když bude lang v session prázdný, tak mu šoupni nějakej default, třeba cs.
V šabloně s jazyky by pak mělo stačit:
<a href="{plink changeLang! 'cs'}">česky</a>
<a href="{plink changeLang! 'en'}">anglicky</a>
Editoval lucass (15. 11. 2009 20:28)
- _Martin_
- Generous Backer | 679
Lucass mě s odpovědí předběhl, ale nevadí – líp bych to ani já nesepsal=)
K té cookie: myslel jsi to tak, že do cookie nechceš ukládat přímo ten jazyk? Protože při použití session slouží cookie jako její identifikátor, čili cookie musí být použita. Možná jsi to přesně tak myslel – jen chci mít jistotu, že si rozumíme.