Symfony 5. ¿Cómo traducir e internacionalizar el framework?

Ahora que te has decidido por actualizar tu producto digital a la versión 5 de Symfony, es muy probable que necesites que tu aplicación se traduzca al castellano u otro idioma.

La buena noticia es que el proceso de internacionalización (i18n) en Symfony 5 es muy semejante a las versiones anteriores, como por ejemplo en la versión 4.  Sin embargo, creo que hoy vale la pena hacer un repaso contigo sobre cómo traducir e internacionalizar Symfony.

¿Qué es internacionalización?

Internacionalización es un término que se refiere al proceso de abstraer cadenas de caracteres de tu aplicación a una capa donde se pueden traducir en función de la ubicación, o idioma y país del usuario. Es el proceso que te permite traducir tu instalación de Wordpress, o Drupal a otros idiomas. Symfony también está preparado para ayudarte en este proceso.

Instalación del componente Translation

Una vez hayas instalado Symfony en tu máquina, debes instalar también el componente Translation y habilitar el servicio de traducción de Symfony. En tu consola ejecutas el siguiente comando:

composer require symfony/translation para instalar el componente

Si accedes ahora a tu sistema de carpetas verás que el comando anterior ha creado un fichero nuevo de configuración. Este fichero llamado translation.yaml te permite definir la configuración regional predefinida (locale) de tu aplicación, y donde los ficheros de traducción estarán localizados con default_path.

Configuración del servicio

La configuración regional predefinida utilizada en las traducciones es la que está almacenada en la petición, normalmente con un atributo _locale en tus rutas. ¡Lo veremos más adelante!

Por último, si necesitas establecer una configuración regional predeterminada para usarla si no existe, por ejemplo en la URL, puedes ajustarlo definiendo default_locale para el framework.

Configuración del default_locale en framework

A partir de este momento, puedes utilizar el servicio de traducción (Translator) para traducir bloques de texto - los mensajes de Symfony - usando el método trans().

Ejemplo básico de trans()

Ejemplo básico de trans()

Para que trans() funcione correctamente necesitas decirle a Symfony como traducir el mensaje “Translate me Symfony”. Esto es tan “fácil” como crear un “diccionario” de traducciones en el formato que más te guste. XML, YAML, y PHP son las opciones disponibles en este momento.

Utilizando YAML, puedes declarar y traducir “Translate me Symfony” de la siguiente forma:

Traducción en Yaml

Symfony intentará traducir el mensaje basandose en la configuración regional predefinida (locale) del usuario. Si el lenguaje del usuario es es_ES, el mensaje será traducido a “Traduceme Symfony”, y ya lo tienes - ¿simple?

Formato del mensaje

De modo a traducir un mensaje que contenga variables, o que contenga algún plural basado en esta variable, Symfony sigue la sintaxis de ICU MessageFormat para hacerlo, usando la clase MessageFormater de PHP.

Gracias a ello, puedes usar placeholders de mensajes, o reglas de pluralización.

Puedes probar los ejemplos de ICU MessageFormatter aquí.

Ejemplo de placeholder para una variable simple‌‌
Ejemplo con reglas de pluralización

Traducción en las plantillas

De la misma forma que has declarado trans() para traducir tu cadena de caracteres en PHP, en tu controlador, además podrás hacerlo en tus plantillas de Twig. El sistema es tan potente e inteligente que te permite utilizar etiquetas (Tags) para traducir mensajes de bloques de texto estáticos, o filtros te Twig para traducir textos de variables y expresiones complejas.

Ejemplo de etiquetas de Twig
Ejemplo de filtros de Twig

¿Hay alguna diferencia entre etiquetas y filtros?

Las etiquetas y los filtros tienen el mismo efecto en Symfony. La diferencia entre las dos características es que los filtros permiten el escape automático de salida.

Por tanto, si quieres que tus mensajes traducidos no tengan la “salida escapada”, debes aplicar el filtro raw, después del filtro de translation.

¿Que es app?

Seguro que te has fijado en ‘app’ después de mi nombre. ‘app’ es el dominio de traducción que puedes definir para toda la plantilla de Twig, utilizando un simple etiqueta: {% trans_default_domain 'app' %}. ¿Cuál es la función del dominio de traducción?

¿Puedo almacenar traducciones en una base de datos?

Sí, puedes usar una base de datos, u otro tipo de almacenamiento proporcionando una clase personalizada que implemente la interfaz LoaderInterface.

¿Cómo trabajar con la configuración regional predefinida del usuario?

Como hemos dicho anteriormente, la configuración regional del usuario actual se almacena en la petición, y puedes acceder a ella mediante el objeto Request de Symfony.

Si quieres ajustar la configuración, pues crear un detector de eventos personalizado para que lo ajuste antes de cualquier otra parte del sistema:

Ojo: tu detector debe ser llamado antes de LocaleListener. Esto significa también que usar $request->setLocale() en un controlador es demasiado tarde para afectar el traductor.

La configuración regional y la URL

Ruta de Symfony con la variable _locale

Configurando la ruta de esta manera, Symfony hace todo el trabajo sobre Request automáticamente. Así, si un usuario visita "/es/product", la configuración regional se ajusta automáticamente como la configuración predefinida para la petición actual.

Esta acción también tiene sentido si estás utilizando el componente FOSRestBundle y necesitas internacionalizar las URLs de tu API.

Traducción para la API

En tu API también puedes servir el contenido de acuerdo con el idioma de usuario. Una de las formas de lograrlo es hacer que tus rutas, o endpoints tengan integrados el parámetro _locale.

Conclusión

Esto es todo por hoy. A partir de ahora ya puedes crear una aplicación internacionalizada en Symfony sin mucho esfuerzo, y utilizar el método trans() para envolver los mensajes, traducir cada uno de los mensajes en tus diferentes ficheros de traducción de mensajes, y gestionar la configuración regional del usuario almacenada en la petición.

¿Qué te parece el sistema de internacionalización de Symfony?
Si necesitas ayuda desarrollando un sistema multilingüe en PHP y Symfony, ¡no dudes en contactarnos!

Foto:  Tessa Kavanagh from Pixabay

Fuentes: