Využití Filter_table a parametru lang

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

Krásný sobotní večer :)
Prosím vás o radu, jak v Routách zkombinovat multijazyčnost a překlad presenterů pomocí filter_table. Pročítal jsem popis od Filipa Procházky (viz https://pla.nette.org/…ru-ve-filtru ), ale začínám v tom mít trochu zmatek.
Jednak v tom návodu se kdesi záhadně z ArticleModel stane PageModel, pak se ztratí parametr <lang>…ale to není teď podstatné :)

Rád bych měl routy ve stylu:
…/cz/pocasi
…/sk/pocasie apod.

Pro překlad presenterů nechci využívat databázi, ale jen prostě pole. Pro CZ zvlášť, pro SK zvlášť.

<?php
 $cz = array(
	'pocasi' => 'Weather',
	...
);
 $sk = array(
	'pocasie' => 'Weather',
	...
);
?>

Ale netuším, jak v RouterFactory do FILTER_TABLE přidat to správné pole právě podle parametru <lang>

<?php
class RouterFactory {

    public function createRouter() {

    $router[] = $route = new FilterRoute('[!<lang [a-z]{2}>/]<presenter>/<action>/<id>', array(
        'lang' => 'cz',
        'presenter' => array(
            Route::FILTER_TABLE => ???? // Jak sem vložit to správné pole?
        'action' => 'default',
        'id' => NULL
    ));
?>

Zkoušel jsem podle Filipa využít jeho FilterRoute a metodu $route->addFilter(…), ale bez úspěchu. Prosím o nakopnutí správným směrem. Děkuju :)

ras
Člen | 135
+
0
-

Bohosu napsal(a):
Rád bych měl routy ve stylu:
…/cz/pocasi
…/sk/pocasie apod.

Pro překlad presenterů nechci využívat databázi, ale jen prostě pole. Pro CZ zvlášť, pro SK zvlášť.

Možná to nebude elegatní, ale přes dvě routy to udělat jednoduše půjde.
Osobně bych pole měl uspořádané spíše podle presenter/action než podle jazyka, ale půjde to tak i tak.

Takže v RouterFactory.php si vytvoříme dvě proměnné

static private $presenters = array(
	'Home' => array(
		'cz' => NULL,
		'sk' => NULL
		),
	'Sale' => array(
		'cz' => 'prodej',
		'sk' => 'predaj'
		)
	);

static private $actions = array(
	'default' => array(
		'cz' => NULL,
		'sk' => NULL
		),
	'add' => array(
		'cz' => 'pridat-zbozi',
		'sk' => 'pridat-tovar'
		)
	);

A pak v RouterFactory.php pořešíme routu

class RouterFactory {

    public function createRouter() {

	$router = new RouteList();
	$router[] = new Route('/cz/<presenter>/<action>', array(
		Route:PRESENTER_KEY => array(
			Route::VALUE => 'Home',
			Route::FILTER_TABLE => self::getPresenters('cz')
			),
		Route:ACTION_KEY => array (
			Route::VALUE => 'default',
			Route::FILTER_TABLE => self:: getActions('cz')
			),
		));

Druhá routa pro SK je věřím také jasná.

No a v Router Factory pak ještě potřebuješ ty dvě funkce, které to zařídí, tj.

static private function getPresenters($lang)
{
	foreach (self::$presenters AS $key=>$item) {
		$return[$item[$lang]] = $key; // nevim, zda to nema byt obracene tj. $return[$key] = $item[$lang];
	}
	return $return;
}
static private function getActions($lang)
{
	foreach (self::$actions AS $key=>$item) {
		$return[$item[$lang]] = $key; // nevim, zda to nema byt obracene tj. $return[$key] = $item[$lang];
	}
	return $return;
}

Netestoval jsem to, ale snad je to OK. Neříkám, že je to krásné, ale bude to funkční.

Hezký den přeji.

Radek

pseudonym
Člen | 57
+
0
-

Ahoj,
otestoval som to a funguje to – az na to, ze Nette nepozna konstanty Route::PRESENTER_KEY a Route:ACTION_KEY. Pouzil som namiesto toho 'presenter' a 'action' a funguje to.

Jan Suchánek
Člen | 404
+
0
-

@pseudonym: ale přešně tohle Hosiplan má funkční s parametry včetně $lang. Tzn: jediná routa.

class RouterFactory {

    public function createRouter() {

	    $router = new RouteList();
	    $route[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY);
	    $route = new FilterRoute('[<lang [cs|en|de]{2} >/]<presenter>[/<action>][/<id [0-9]>]', array(
			'presenter' => 'Homepage',
	        'action' => 'default',
	        'lang' => 'cs',
	        'id' => NULL,
		);
		$route->addFilter('presenter', 'ExampleUrlModel::presenterIn', 'ExampleUrlModel::presenterOut');
		$route->addFilter('action', 'ExampleUrlModel::actionIn', 'ExampleUrlModel::actionOut');

		/*
			Třída ExampleUrlModel obsahuje 4 statické metody včetně statických parametrů,
			což je transparentnější ne?
		*/

		$router[] = $route;

		return $router;
	}

V routě se u FilterRoute volají statické metody třídy UrlModel např. presenterIn a presenterOut a vždy dostatne konkrétní parametr, nebo dokonce může dostat všechny parametry, záleží na tobě, nebo dokonce můžeš FilterRoute injectnout RouteManager, který bude obsahovat UrlRepository + UrlCache a můžeš tahat url z databáze a cachovat.

Trošku OT: Kdybych chtěl přesto používat DB a překládat slug a presenter, jak by jste třídu s připojením či repositář s routrem používali? Napadá mě injectnutí a nebo událost, co je lepší? Nebo existuje ještě něco fikanějšího?

class RouterFactory {

    public function __construct(Model\RouterManager $routerManager)
    {
	$this->routerManager = $routerManager;
    }

    public function createRouter() {

        $router = new RouteList();
        $route[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY);
        $route = new FilterRoute('[<lang [cs|en|de]{2} >/]<presenter>[/<action>][/<id [0-9]>]', array(
            'presenter' => 'Homepage',
            'action' => 'default',
            'lang' => 'cs',
            'id' => NULL,
        );

        $route->addFilter($this->routerManager, 'presenter');

        $router[] = $route;

        return $router;
    }

nebo

class RouterFactory {

	/*
		Může obsahovat Repository + Cache a je potvora vytvořená jako služba, která může být
		přístupná i v presenteru pro případné změny url je vždy invalidovaná cache.
		Vycházím ze staršího routru, s tím že chci používat DI
		https://forum.nette.org/cs/3290-routy-zavisle-na-databazi#p23853
	*/

    public function __construct(Model\RouterManager $routerManager)
    {
		$this->routerManager = $routerManager;
    }

    public function createRouter() {

		...

		$routeManager = $this->routeManager;

		$route->onFilter[] = function($params, $way) use($routeManager){
			if(FilterRouter::WAY_IN === $way){
				return $routeManager->filterPresenterIn($params);
			}

			return $routeManager->filterPresenterOut($params);

		};

		...
    }

Nebo je lepší používat https://doc.nette.org/…tion/routing#…

Pochlubte se, jaké máte řešení vy?

Omlouvám se za OT a případné chybky, berte prosím příspěvek jako úvahu.

Editoval jenicek (22. 10. 2013 13:26)