Cómo realizar un sitio multilenguaje con yii mediante get
Cuando uno realiza una página multilenguaje (totalmente traducida), no desea que cuando uno hace click en ver en otro idioma la página se recargue y empiece desde el inicio nuevamente. Para que esto no suceda, se puede utilizar una variable en cada request y actualizar el lenguaje y la forma de cambiar el lenguaje es realizar un request que modifique la inforamción del lenguaje en la cookie,
Sabemos que a veces es muy molesto utilizar las cookies para mantener el lenguaje ya que si el usuario cierra la sesión y uno destruye la misma, la selección del lenguaje se pierde; si uno lo realiza mediante cookies hace que cada request al sitio envie más información que la necesaria (tanto para imágenes como para un archivo) y si uno lo hace mediante GET, todas las páginas deben tener esta información lo cual es muy trabajoso. Como en Yii siempre utilizamos el método createUrl de CUrlManager, entonces hacer que se incluya el lenguaje en cada link es tan simple como hacer que automáticamente se agregue cuando uno llama a este método. Esto funciona correctamente en todos los casos pero siempre se debe recargar la información del lenguaje mediante el método que se utiliza cada vez que un request llega para que todo lo que se cree se encuentre en el idioma correcto. Creemos ventajoso usar el get ya que esto deja que cada idioma se encuentre en la URL y a su vez ayude en el SEO del sitio. Es por eso que nuestra propuesta esta basada en GET, es muy simple y con solo 3 pasos uno puede tener su sitio utilizando multilenguaje sin problemas.
Paso 1
Extender el componente CUrlManager para que automáticamente agregue el lenguaje a cada uno de los links creados.
class MyCUrlManager extends CUrlManager
{
public function createUrl($route,$params=array(),$ampersand='&')
{
if (!isset($params['language']))
$params['language']=Yii::app()->language;
return parent::createUrl($route, $params, $ampersand);
}
}
Paso 2
Se modifica el config para que la aplicación utilice el componente recién creado MyUrlManager en lugar del componente CUrlManager
return array(
... // more config here
'language'=>'pt',
'sourceLanguage'=>'en',
... // more config here
// application components
'components'=>array(
'urlManager'=>array(
'class'=>'application.components.MyCUrlManager',
'urlFormat'=>'path',
'rules'=>array(
'/home'=>'site/index',
'/list/-'=>'item/list',
'/<_a:(contact|login|signup|search|logout)>'=>'site/<_a>',
'/<_c:\w+>'=>'<_c>',
'/<_c:\w+>/<_a:\w+>'=>'<_c>/<_a>',
'/admin'=>'admin/admin',
'admin'=>'admin/admin',
'admin/<_c:\w+>/<_a:\w+>'=>'admin/<_c>/<_a>',
'admin/<_c:\w+>'=>'admin/<_c>',
'/admin/<_c:\w+>/<_a:\w+>'=>'admin/<_c>/<_a>',
'/admin/<_c:\w+>'=>'admin/<_c>',
),
),
... // more config here
);
Paso 3
Extiendo la clase CController para que en cada parte de la aplicación se actualice el lenguaje al que esta indicado en el QueryString y utilizo esta nueva clase creada en todos mis controladores del proyecto.
class MultilanguageController extends CController{
//put your code here
public function __construct($id,$module=null){
parent::__construct($id,$module);
Yii::app()->language = (isset($_GET['language']))?$_GET['language']:Yii::app()->language;
}
public function createMultilanguageReturnUrl($lang='pt'){
$arr = array('language'=>$lang);
if (count($_GET)>0){
$arr = $_GET;
$arr['language']= $lang;
}
return $this->createUrl('', $arr);
}
}
Paso 4 (opcional)
En cada lugar que quiero poner un link que cambie de lenguaje mi aplicación, utilizo la siguiente forma:
echo CHtml::link('ver en español', $this->createMultilanguageReturnUrl('es')) . ' | ' . CHtml::link('ver en español', $this->createMultilanguageReturnUrl('en'));
En donde el parametro enviado a createMultilanguageReturnUrl es el lenguaje en el que se quiere traducir la página actual.
Muy buen artículo, lo voy a llevar a la práctica pronto!
Buenas, creo que te has equivocado en el codigo, en el primer paso extiendes de CControler, no de CUrlManager, y tampoco coincide el nombre de la clase…
muchas gracias por el artiuculo, deberías ponerlo en el cookbook!
abrazo
Si, ya lo arreglé… Gracias!
Oye no entendí lo del paso 3, me lo puedes explicar con manzanas, por favor!!!
En el paso 3 lo que hago es extender el controlador así cada vez que ingreso le aviso a la aplicación en que lenguaje debe estar.
Y que pasa si tenemos el urlManager con alguna regla tan simple como ‘urlFormat’=>’path’? ya no funcion la seleccion de idioma.
A como le enteidno el querystring desaparece y ya no se puede interpretar el lenguage correctamente en UrlManager->createUrl (al hacer el cambio de idioma en el selector, la pagina se regarga con la nueva ruta correctamente, pero la vista no cambia con el lenguage seleccionado)
Entindes lo que digo?
El problema esa en el $_GET['language'] de __construct que daria ‘undefined’. No tengo idea de como arreglarlo, que se te ocurre.
Si funciona, solo que lo envía como parámetro de GET
y en que ubicación del proyecto colocas la clase que extiende el Ccontroller y como hacces para que la aplicacion sepa que ya no va a usar el CController si no tu nueva clase que va a hacer las veces de CController ??