Překlad rout pomocí Kdyby/Translation

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

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.

romiix.org
Člen | 343
+
-3
-

Toto by mohlo pomôcť: https://pla.nette.org/…ru-ve-filtru

David Matějka
Moderator | 6445
+
+1
-

asi bych to nekomplikoval a pouzil FILTER_TABLE :)

@romiix.org to melo vyznam pred tim, nez byly pridany globalni filtry

BuGeR
Člen | 45
+
+1
-

Davide děkuji. Jak mám ale použít FILTER_TABLE, zároveň s Kdyby/Translation? Potřebuji mít ty překlady v externím slovníku.

hury
Člen | 56
+
0
-

Ahoj,
resim upne ten samy problem, nejake funkcni reseni s ukazkou kodu prosim?

potreboval bych mit vyslednou URL dle jazyku

/prihlasit/zapomenute-heslo
/en/sign/lost-password

preklady url bych rad pres doplnek Kdyby/Translation

diky za uzitecne rady :-)

newPOPE
Člen | 648
+
0
-

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

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

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.

BuGeR
Člen | 45
+
0
-

A jaká je tedy nejlepší cesta?

Azathoth
Člen | 495
+
0
-

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