Symfony i18n: internacionalización de la web, entrada a la web

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.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *