Multijazyčnost, routování a persitentní parametr
- Inza
- Člen | 330
Mám ještě jeden dotaz:
Chceme mít na serveru routy ve tvaru /cs/foo/bar
a /en/foo/bar
a aby /foo/bar byla one way na /en/foo/bar pokud už má user v session jazyk en jako zvolený
A četl jsem všechny posty a dostupnou doku o routování a vymýšlel vhodné řešení.
nejdříve jsem dal do rout ten jazyk jako nepovinný parametr, ale to zkrachovalo na tom, že jelikož je první tak by potom muselo být nepovinné všechno a to udělat u všech rout nejde…
Tak jsem udělal jazyk povinným, ale potom je ho nutné u všech redirectů předávat a navíc ho mít v těch metodách jako argument vypsaný. Což je opruz. A tak se chci zeptat zda je nějaké lepší řešení.
Vítek říkal něco o persistentním parametru v base presenteru, ale to si neumím úplně představit. a Bylo by potom nutné ho psát jako argument v hlavičkách actionů?
Nebo je ještě nějaké jiné lepší řešení?
- PetrP
- Člen | 587
lol
abstract class BasePresenter extends Presenter
{
/** @persistent */
public $lang;
protected function startup()
{
parent::startup();
if (!isset($this->lang))
{
$this->lang = $this->getHttpRequest()->detectLanguage(array('en', 'cs'));
$this->canonicalize();
}
}
}
Route::addStyle('lang', NULL);
Route::setStyleProperty('lang', Route::PATTERN, '[a-z0-9]{1,3}');
$router[] = new Route('<lang>/<foo>/<bar>', array(
'presenter' => 'Default',
'action' => 'default',
));
$router[] = new Route('<foo>/<bar>', array(
'lang' => NULL,
'presenter' => 'Default',
'action' => 'default',
), Route::ONE_WAY);
{link Neco:nekam parametry dle libosti lang se mi porad prenasi}
{link this 'lang'=>'en'} a ted zmenim lang
Pripadne si muzes na lang udelat FILTER_IN a FILTER_OUT a tahat je vuci databazi, a v aplikaci pak pracovat jen z id jazyka, kdyz budes mit zajem tak ti to popisu.
- Patrik Votoček
- Člen | 2221
Možná bych raději vyděl verzi bez anotací (funguje všude –
s anotacemi nemusí fungovat – eAccelerator). Aneb místo
/** @presistent */
:
/**
* Get persistent parameters
*
* @return array persistants
*/
public static function getPersistentParams()
{
return array('lang');
}
PetrP napsal(a):
Pripadne si muzes na lang udelat FILTER_IN a FILTER_OUT a tahat je vuci databazi, a v aplikaci pak pracovat jen z id jazyka, kdyz budes mit zajem tak ti to popisu.
Možná vím jak to myslíš ale zajímalo by mě to…
- PetrP
- Člen | 587
vrtak-cz napsal(a):
Možná vím jak to myslíš ale zajímalo by mě to…
Route::addStyle('lang', NULL);
Route::setStyleProperty('lang', Route::PATTERN, '[a-z0-9]{1,3}'); // tohle je mozna i ted zbytecne, protoze lang muze nabyvat jen mnou stanovenejch hodnot.
Route::setStyleProperty('lang', Route::FILTER_OUT, array($model,'getLangNameById'));
Route::setStyleProperty('lang', Route::FILTER_IN, array($model,'getLangIdByName'));
$router[] = new Route('<lang>/<foo>/<bar>',array(
'presenter' => 'Default',
'action' => 'default',
));
// Tady stoji za povsimnuti ze model vraci pripadne i NULL kdyz lang neexistuje, protoze to pak routu zastavi, takže se ti nestane ze v <lang> budes mit neexistujici jazyk (nutno podotknout ze lang nesmi mít v route defaultni hodnotu)
interface IModel
{
/**
* @param int
* @return string|void
*/
public function getLangNameById($id);
/**
* @param string
* @return int|void
*/
public function getLangIdByName($name);
}
- Oggy
- Člen | 306
mám takový dotaz.. jak toto:
bootstrap
<?php
$application->onStartup[] = 'Database::initialize';
// Step 4: Setup application router
$router = $application->getRouter();
// mod_rewrite detection
if (function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) {
$jazyk = new Jazyky();
Route::addStyle('lang', NULL);
Route::setStyleProperty('lang', Route::FILTER_OUT, array($jazyk,'getId'));
Route::setStyleProperty('lang', Route::FILTER_IN, array($jazyk,'getUrl'));
$router[] = new Route('index.php', array(
'lang' => 'cs',
'module' => 'Front',
'presenter' => 'Home',
), Route::ONE_WAY);
$router[] = new Route('<lang>/<presenter>/<action>/<id>', array(
'module' => 'Front',
'presenter' => 'Home',
'action' => 'default',
'id' => NULL,
));
} else {
$router[] = new SimpleRouter('Front:Home:default');
}
// Step 5: Run the application!
$application->run();
?>
třída jazyky
<?php
class Jazyky
{
public function getId($url)
{
$query = dibi::select('jazykId')->from('jazyky')->where('url = %s' ,$url);
$id = $query->fetch()->jazykId;
return (int) $id;
}
public function getUrl($id)
{
$query = dibi::select('url')->from('jazyky')->where('jazykId = %i',$id);
$url = $query->fetch()->url;
return $url;
}
}
?>
Jde o to, že při vytváření instance třídy Jazyky ještě nejsem
připojen k databázi.. to se stane až v okamžiku $application->run();
… $application->onStartup[] = ‚Database::initialize‘; ..
nebo jsem to špatně pochopil?
Editoval Oggy (25. 8. 2009 21:58)
- Honza Marek
- Člen | 1664
Můžeš se připojit už v bootstrapu normálním zavoláním Database::initialize(), ne?
Potom tip, místo $query->fetch()->url můžeš použít $query->fetchSingle().
- Oggy
- Člen | 306
Honza M. napsal(a):
Můžeš se připojit už v bootstrapu normálním zavoláním Database::initialize(), ne?
Potom tip, místo $query->fetch()->url můžeš použít $query->fetchSingle().
ok..jj..jen jsem chtěl vědět jestli to takto řeší i zkušení:-)
tip:díky.. můžu se ještě zeptat jaký rozdíl mězi těmihle funkcemi je?
- redhead
- Člen | 1313
fetchAll ti vrátí objekt resp. pole a fetchSingle ti vrátí první hodnotu sloupce z databáze. Takže v tomto případě, když potřebuješ vytáhnout pouze url a nic jiného, tak je to jednodušší řešení.
$query->fetch()->url; // == 'http://...'
$query->fetchSingle(); // == 'http://...'