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.

Victor

Autor: Victor

Desarrollador web - Formador online - Blogger

Compartir este post

1 Comentario

  1. Estoy realizando la internalización con symfony 3 y esta funcionando correctamente, pero solo tengo problemas cuando el idioma es English(en), no me lee el archivo messages_en.yml, me escribe en la vista el nombre del tag, eje: string_traducir, cuando con los otros lenguajes si me escribe el valor que consigue del string_traducir.

    Sabes por que me ocurre esto?

    Gracias saludos

    Responder

Poner un comentario

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