Využití Filter_table a parametru lang
- Bohosu
- Člen | 24
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
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
- Jan Suchánek
- Člen | 404
@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)