Puede ser algo trivial, pero es el punto de partida para iniciar la internacionalización de una web. Me refiero a la llegada del usuario, recogida del código de idioma y región del navegador, se comprueban los idiomas disponibles y posteriormente se le redirige a la página de su idioma correspondiente.
Es mucho más sencillo que lo que puede parecer a priori, pero claro está, hay que tener claras un par de cosas que si no después se complica.
El usuario llega a la web
En este punto, tenemos un usuario que llega a la web. Ahora es el momento de elegir el idioma en que le vamos a mostrar la página web al usuario. Que podemos hacerlo de dos formas diferentes: eligiendo el idioma por defecto o con el idioma que nos sugiera el navegador.
Vamos a empezar con un ejemplo de controlador que recibe la visita inicial del usuario:
<?php
namespace FrontBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;
use SymfonyComponentHttpFoundationRequest;
/*
* Controlador de ejemplo para empezar a traducir una web.
* Sólo tiene las dos rutas necesarias para empezar la navegación traducida
* Se necesita de la entidad Idioma para tener los idiomas disponibles.
*/
class DefaultController extends Controller
{
/**
* Esta ruta es la página de inicio. Simplemente recibe al visitante
* busca entre los idiomas publicados y le redirige a la ruta siguiente
* poniendo el código del idioma en la URL.
*
* @Route («/», name=»iniciototal»)
*/
public function inicioTotalAction(Request $request)
{
$manager = $this->getDoctrine()->getManager();
// Creamos el array de idiomas disponibles que se obtienen de la
// entidad Backbundle:Idioma, aquí lo que hacemos es recuperar de la
// BD los idiomas publicados guardando en un array los códigos de idioma.
$idiomas = $manager->getRepository(‘BackBundle:Idioma’)->findBy(array(
‘publicado’ => true
));
$idiomasarray = array();
foreach ($idiomas as $idioma) {
$idiomasarray[] = $idioma->getCodigo();
}
// Consulta los lenguajes preferidos del navegador, comprueba
// los que tenemos disponibles disponibles devolviendo el primero
// que tenemos disponible de los preferidos por el navegador.
$codigoLocale = $request->getPreferredLanguage($idiomasarray);
// Redirigimos la visita a la ruta de abajo poniéndole el código
// del idioma.
return $this->redirect($this->generateUrl(‘inicio’, array(
‘_locale’ => $codigoLocale
)));
}
/**
* En esta ruta ya tenemos un código de idioma establecido,
* podemos hacer a partir de aquí todo. El resto de rutas de la aplicación
* deben tener la ruta de la forma «/{_locale}/resto/de/la/ruta»
* para continuar navegando en el idioma actual.
*
* @Route («/{_locale}/», name=»inicio»)
* @Template
*/
public function inicioAction($_locale)
{
$manager = $this->getDoctrine()->getManager();
// Aquí tenemos ya el código de idioma en la variable especial $_locale
// con esto ya podemos consultar la BD con el idioma que tenemos en curso
// mostrándole al usuario todo traducido o lo que sea que necesitemos hacer.
return array();
}
}
A partir de aquí ya tendremos la visita con el idioma. La variable _locale es una variable especial. Se puede consultar en las plantillas Twig poniendo en la plantilla:
{{ app.request.locale }}
La variable _locale es especial porque se establece a partir del momento en que la establecemos nosotros. Se nos puede ocurrir obtener el _locale de la aplicación con la instrucción siguiente en el controlador:
$this->getRequest()->getLocale();
Si hacemos esto en el controlador, en la ruta «iniciototal», no obtendremos el _locale del navegador, si no que obtendremos el _locale puesto en el fichero de parámetros de configuración parameters.yml. A mi me ha pasado y lleva a confusión. Podemos usar ésta última instrucción y tendremos el código de idioma actual si lo hemos establecido recibiendo el _locale en la ruta poniendo siempre al principio del resto de las rutas el _locale. Como indico en el comentario del código, usando rutas de la forma «/{_locale}/resto/de/la/ruta».
Es decir, tendremos que recibir la variable {_locale} en todas las rutas para poder usar en el controlador:
$this->getRequest()->getLocale();
.. y que nos devuelva correctamente el idioma. Si lo que queremos es ver el _locale que nos pide el navegador podemos ejecutar lo siguiente:
$request->getPreferredLanguage();
Espero que sirva de ayuda.
Un saludo.