jayrulez
(Waprave)
September 14, 2009, 11:13pm
1
I am trying to implement i18n in my application…
The code i have so far gets the job done but i would like if someone could suggest a better and more effecient way to go about it if possible.
This is what i have done:
i created a base controller in components which all other controllers extend, this is the source
<?php
class BaseController extends CController
{
public $app;
.............
public function init()
{
$this->app = Yii::app();
//$this->_setTheme();
$this->_setLanguage();
}
..........
private function _setLanguage()
{
if(isset($_GET[$this->app->params['varLanguage']]))
{
$language = $_GET[$this->app->params['varLanguage']];
}else if(isset($_COOKIE[$this->app->params['varLanguage']]))
{
$language = $_COOKIE[$this->app->params['varLanguage']];
}else{
$language = $this->app->params['defaultLanguage'];
}
if(!array_key_exists($language,$this->app->params['languages']))
{
$language = $this->app->params['defaultLanguage'];
}
if(!isset($_COOKIE[$this->app->params['varLanguage']])||$_COOKIE[$this->app->params['varLanguage']]!=$language)
{
setcookie($this->app->params['varLanguage'],$language,$this->app->params['cookieExpire']);
}
$this->app->setLanguage($language);
}
..........
}
and i have this in my config file
'params'=>array(
........
'cookieExpire'=>time()+3600,
........
'defaultLanguage'=>'en_us',
'varLanguage'=>'language',
'languages'=>array(
'en_us'=>array(
'name'=>'English (US)',
'encoding'=>'utf-8',
),
/*'zh_cn'=>array()*/
),
),
phpdevmd
(Phpdevmd)
September 15, 2009, 7:57am
2
Setting a language looking more or less optimized. I would recommend using a wrapper class for managing cookies:
<?php
/**
* Manage Cookies
*/
class MCookie
{
/**
* Get a cookie value
* @param string $name
* @return string
*/
public static function get($name)
{
$cookies=Yii::app()->request->getCookies();
return is_object($cookies[$name]) ? $cookies[$name]->value : null;
}
/**
* Whether has a cookie
* @param string $name
* @return bool
*/
public static function has($name)
{
$cookies=Yii::app()->request->getCookies();
return is_object($cookies[$name]);
}
/**
* Set a cookie value
* @param string $name
* @param string $value
* @param array $params
*/
public static function set($name,$value,$params=array())
{
$cookie=new CHttpCookie($name,$value);
$cookie->expire=time() + 3600*24*30; // by default to 30 days from now
if(isset($params['expire']))
{
if(is_numeric($params['expire']))
{
$cookie->expire=(int)$params['expire'];
// don't forget, expire is a timestamp
$cookie->expire<time() && ($cookie->expire += time());
}
else
{/*write log*/}
}
if(isset($params['domain']))
{
if(is_string($params['domain']) || is_numeric($params['domain']))
$cookie->domain=(string)$params['domain'];
else
{/*write log*/}
}
if(isset($params['path']))
{
if(is_string($params['path']) || is_numeric($params['path']))
$cookie->path=(string)$params['path'];
else
{/*write log*/}
}
if(isset($params['secure']))
{
if(is_bool($params['secure']))
$cookie->secure=$params['secure'];
else
{/*write log*/}
}
if(isset($params['httpOnly']))
{
if(is_bool($params['httpOnly']))
$cookie->httpOnly=$params['httpOnly'];
else
{/*write log*/}
}
$cookies=Yii::app()->request->getCookies();
$cookies[$name]=$cookie;
}
/**
* Unset a cookie
* @param string $name
*/
public static function unsetIt($name)
{
$cookies=Yii::app()->request->getCookies();
unset($cookies[$name]);
}
}
then instead of
if(isset($_COOKIE[$this->app->params['varLanguage']]))
use
if(MCookie::has($this->app->params['varLanguage']))
and so on…
Maxximus
(Maxximus007)
September 25, 2009, 1:42pm
3
Using a similar function, but as a component. Not really sure why you do $this->app = Yii::app();, and perhaps use CHttpCookie. I also look at Yii::app()->request->preferredLanguage, so see if I can offer that language right away.
To go a bit further:
My LangHandler component adds a 2-letter parameter before the path. But for SEO reasons, it would be a lot nicer to have translated paths in the URL. This would require much more than that, and can (will) make things complicated.
Currently I do this for some urls by defining routes, but that’s less than perfect… Still I can’t get it out of my head . Anyone already done something like that?
PS: if the requested language could be determined before routes something like this could work:
Yii::t('route', 'controller').'/_a' => 'controller/_a',