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:
Y si entramos con inglés:
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.