Internacionalización en Symfony3

Hoy vamos a ver cómo funciona la internacionalización en Symfony3 para traducir los strings estáticos que tengamos en nuestra aplicación web. La forma de hacer traducciones en Symfony 3 es prácticamente igual que en Symfony2.

Antes de nada acuerdate de que en fichero config.yml tienes que tener el translator activado

parameters:
    locale: en

framework:
    #esi:             ~
    translator:      { fallbacks: ["%locale%"] }

Lo primero que vamos a hacer es crear un Listener, el listener se lanzará cada vez que hagamos una petición http.

Crearemos un directorio EventListener en la raíz de nuestro bundle.

<?php
namespace AppBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class LocalListener implements EventSubscriberInterface
{
    private $defaultLocale;

    public function __construct($defaultLocale = 'en')
    {
        $this->defaultLocale = $defaultLocale;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        if (!$request->hasPreviousSession()) {
            return;
        }

        // Comprueba si le llega el parametro _locale de la ruta por la URL
        if ($locale = $request->attributes->get('_locale')) {
            $request->getSession()->set('_locale', $locale);
        } else {
            // Si no le llega utiliza el defaultLocale en este caso inglés
            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
        }
    }

    public static function getSubscribedEvents()
    {
        return array(  
            KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
        );
    }
}

Añadimos el listener al fichero app/config/services.yml

services:
    app_bundle.locale_listener:
        class: AppBundle\EventListener\LocalListener
        arguments: ["%kernel.default_locale%"]
        tags:
            - { name: kernel.event_subscriber }

Ahora podemos crear una acción para cambiar el idioma de la sesión

public function indexAction(Request $request) {

     var_dump($request->getLocale());

	return $this->render('default/index.html.twig', array(
	  'base_dir' => realpath($this->container->getParameter('kernel.root_dir') . '/..'),
	  'locale' => $request->getLocale(),
	));
}

Y creamos una ruta para acceder a ella

app_default:
    path:     /{_locale}/default
    defaults: { _controller: AppBundle:Default:index }

Ahora podemos crear el directorio app/Resources/Translations y dentro crear ficheros yml para los strings a traducir.

Voy a crear el fichero messages.en.yml para el inglés con tantos strings para traducir como queramos:

string_traducir: Translate this please

También crearé el fichero para el español, messages.es.yml:

string_traducir: Traduceme esto por favor

En la vista podemos mostrar los strings traducidos así:

{% trans %}string_traducir{% endtrans %}

Y en el controlador así:

$this->get('translator')->trans('string_traducir');

Ahora si tratamos de entrar a la ruta con el idioma español nos traduce el string en castellano:

internacionalizacion en symfony3 español

Y si entramos con inglés:

internacionalizacion en symfony3 ingles

Recuerda que el idioma se guarda en la sesión _locale, con lo cual podríamos hacer un sistema más complejo para traducir la base de datos y sacar unos datos u otros en función del lenguaje que tenga la sesión, pero eso ya es otro tema.

Pues con esto ya hemos visto como utilizar la internacionalización en Symfony.

Víctor Robles WEB

Autor: Victor

Desarrollador web - Formador online - Blogger

Compartir este post