Překlad rout pomocí Kdyby/Translation
- BuGeR
- Člen | 45
Dobrý den,
řeším problém s překladem rout. Chci mít adresy na webu ve stylu:
domain.com/lost-password
domain.com/cs/zapomenute-heslo
To znamená, že jeden presenter může odpovídat více názvum.
Používám doplněk Kdyby/Translation.
Do parametru routy jsem vložil globální filtr:
NULL => array(
Route::FILTER_IN => function(array $params) {
return $this->translateIn($params);
},
Route::FILTER_OUT => function(array $params) {
return $this->translateOut($params);
},
)
A k tomu mám tedy 2 metody. Metoda pro FILTER_OUT, tedy translateOut, mi vrátí přeložený presenter pomocí Kdyby/Translation ze slovníku. To funguje v pořádku.
Ten slovník vypadá nějak takto:
presenters:
LostPassword:
name: "ZapomenuteHeslo"
Problém je ale v tom, že nevím jak mám napsat funkci pro FILTER_IN, která dostane přeložený presenter, a musí ho přeložit na „systémový“ název presenteru. V Kdyby/Translation není žádný „opačný“ překlad, nebo něco takového.
Nenapadá vás nějaké řešení? Popřípadě jak tohle řešíte vy?
Děkuji všem za odpovědi.
- David Matějka
- Moderator | 6445
asi bych to nekomplikoval a pouzil FILTER_TABLE :)
@romiix.org to melo vyznam pred tim, nez byly pridany globalni filtry
- newPOPE
- Člen | 648
A co spojit FILTER_TABLE
s Kdyby\Translation
(ale
pozor bude to mäso!)
//$this->translator === instanceof \Kdyby\Translator
'presenter' => [
FILTER_TABLE => [
$this->translator->translate('routing.login_presenter') => 'Login';
...
]
],
'action' => [
FILTER_TABLE => [
$this->translator->translate('routing.forgot_password_action') => 'Login';
...
]
],
Editoval newPOPE (3. 9. 2015 20:40)
- hury
- Člen | 56
koukal jsem na ten clanek https://pla.nette.org/…ru-ve-filtru ale tedy, prijde mi napsany pro cloveka, ktery si vetsinu veci umi dopsat sam, coz v tomto pripade nedokazu :-)
mozna mi chybi nejaka znalost…
mam router:
$route = new FilterRoute('[<locale=cs cs|en>/]<presenter>/<action>', array(
'module' => 'Front',
'presenter' => 'Homepage',
'action' => 'default',
), ((APP_MODE == 'production') ? Route::SECURED : false) );
$route->addFilter('presenter', '\App\RouterModel::urlToTrans', '\App\RouterModel::transToUrl');
$router[] = $route;
a pak RouterModel:
class RouterModel extends Nette\Object
{
/** @var \Kdyby\Translation\Translator @inject */
public $translator;
public static function urlToTrans($url, Nette\Application\Request $request)
{
$lang = $request->getParameter('locale');
// jak sem nactu $this->translator?
if ($lang == 'cs') {
if ($url == 'Clanek') {
return 'Blog';
}
}
else {
if ($url == 'Article') {
return 'Blog';
}
}
}
public static function transToUrl($url, Nette\Application\Request $request)
{
$lang = $request->getParameter('locale');
// jak sem nactu $this->translator?
if ($lang == 'cs') {
if ($url == 'Blog') {
return 'Clanek';
}
}
else {
if ($url == 'Blog') {
return 'Article';
}
}
}
}
zaboha nemuzu prijit na to, jak to nevolat jako statickou tridu… v tom
$route->addFilter
nebo at se to klidne vola jako \App\RouterModel::urlToTrans, ale jak pak se
dostanu na $this->translator?
dokazal by nekdo poradit prosim?
Editoval hury (3. 9. 2015 22:02)
- Filip Procházka
- Moderator | 4668
Překládat routy translatorem není vůbec dobrá cesta, protože translator sám potřebuje locale parametr aby věděl jaký jazyk použít a tedy by sis musel nějak „komplikovaně“ parsovat url ještě předtím než padne do routeru.
- Azathoth
- Člen | 495
@FilipProcházka ale translator může přeci pracovat se všemi
jazyky najednou. Stačí, když si vytahne z translatoru katalog pro daný
jazyk, projde ten katalog a najde si klíč daného překladu a podle něj
překlad v jiném jazyce…akce na pár řádků.
@BuGeR podle mne můžeš použít Kdyby Translation k překladům, ale
budeš muset použít nějaké nezdokumentované features Symfony
Translation.
Jde o to, že translator má v sobě katalog pro každý jazyk. A katalog
v sově drží všechny překlady.
Např. by to vypadalo takhle:
$catalogueCs = $this->translator->getCatalogue('cs');
$catalogueEn = $this->translator->getCatalogue('en');
$arrayCs = $catalogueCs->all();
Helpers::flatten($arrayCs); //prostě funkce, která převede vícedimenzionální pole do dot notation
$key = array_search('českáVerze', $arrayCs);
$arrayEn = $catalogueEn->all();
Helpers::flatten($arrayEn); //prostě funkce, která převede vícedimenzionální pole do dot notation
$translatedToEn = $arrayEn[$key];
ovšem tohle je prasácké, ale obecné pro jakýkoli domain.
Pokud vím, v jakém domainu mám překlady rout, bude to vypadat takto:
$catalogueCs = $this->translator->getCatalogue('cs');
$catalogueEn = $this->translator->getCatalogue('en');
$arrayCs = $catalogueCs->all('routes'); //název domainu (v neonu je u názvů překladových souborů formát: domain.locale.neon)
$key = array_search('českáVerze', $arrayCs);
$translatedToEn = $catalogueEn->get($key, 'routes'); //a v proměnné $translatedToEn mám anglickou verzi.