Internacionalizando javascript en symfony

En este nuevo desafío que he asumido recientemente me encuentro con tener que mantener y mejorar aplicaciones web que están desarrolladas sobre symfony 5. Este es un framework PHP (si, php, no me matéis) que tiene sus cosas buenas y sus cosas malas. Una de las buenas es que permite internacionalizar las aplicaciones sin demasiados problemas… Al menos la parte de html.

Symfony utiliza un sistema de plantillas twig que es donde se pueden realizar las traducciones poniendo {%trans%}cadena{%endtrans%} y luego simplemente tenemos que mantener los archivos de traducción de cada lenguaje y ya toda la magia sucede internamente y sin problemas.

Imagen generada por AI cuando le pedí que me hiciese una imagen para un post de programación

Pero, ¿Qué pasa con las cadenas que generamos en javascript? Los archivos .js se sirven estáticamente sin que pasen por el proceso de sustitución que se hace en los twig, no nos vale poner {%trans%}cadena{%endtrans%} en el js porque ese archivo nunca va a ser tratado por symfony ni por php ya puestos.

La solución que he terminado por implementar se basa en generar un archivo .js con las traducciones en base a una plantilla twig y cargarla cada vez que necesite traducir algo en un js. Para ello solo tenemos que dar estos pasos:

  1. Crear la ruta en routes.yml (o usar un decorador) para /jstrans.js o similar
  2. Crear un controlador para servir ese archivo, por ejemplo JavascriptController.php
  3. Crear un twig para el javascript, por ejemplo jstrans.js.twig
  4. Meter en el twig todas las cadenas y sus traducciones correspondientes
  5. Hacer que jstrans.js se cargue en todas las páginas que necesiten traducciones
  6. usar la función que traduce en los js que lo necesiten.

Aquí os dejo un ejemplo de cada uno de los archivos:

JavascriptController.php

class JavascriptController extends AbstractController
{
    public function __construct()
    {
        $this->config = new Config();
    }

    public function index(): Response
    {
        $response =  $this->render('javascript/jstrans.js.twig', [
            'controller_name' => 'JavascriptController',
        ])->setSharedMaxAge(3600)->setPublic();
        $response->headers->set('Content-Type','text/javascript');
        return $response;
    }
}

jstrans.js.twig

if (typeof jstrans == 'undefined') {

    var jstrans = {
        traducciones: {
            'Seleccionar': '{%trans%}Seleccionar{%endtrans%}',
            'Registros': '{%trans%}Registros{%endtrans%}',
            'No se han encontrado resultados': '{%trans%}No se han encontrado resultados{%endtrans%}',
        },
        // Función que traduce un texto
        translate: function (text) {
            if (jstrans.traducciones[text] != undefined) {
                return jstrans.traducciones[text];
            } else {
                return text;
            }
        }
    };
} else {
    console.log ('jstrans ya está definida');
}

Luego ya se meten las cadenas en, messages.en.yaml,, por ejemplo

Seleccionar: Select
Registros: Registers
No se han encontrado resultados: No results found

Y luego solo hay que usarlo en los archivos js de esta manera:

jstrans.translate("Seleccionar")

Y eso te dará la cadena traducida al idioma en el que se esté navegando.

¿Conoces algún método mejor para conseguir traducciones en los js de un proyecto symfony? déjame un comentario si es así…

Varias versiones php en tu servidor

Esto de las versiones del php me ha traído de cabeza desde que decidieron que algunas versiones iban a ser incompatibles con otras… Tan traumático fue el cambio a php5 que la comunidad ha tardado muchos años en decidirse a utilizar otra versión, tanto que se han saltado un número y ahora vivimos con la versión 7.x. En este caso os dejo la receta para poder cambiar de una versión a otra de php en un servidor ubuntu y así poder probar si algo funciona con la versión más nueva o hay que seguir «pegado a la versión anterior».

Yo me he creado dos archivos para hacerlo: 

switchTo5.6.sh

!/bin/bash
a2dismod php7.2
a2enmod php5.6
update-alternatives --set php /usr/bin/php5.6
update-alternatives --set phar /usr/bin/phar5.6
update-alternatives --set phar.phar /usr/bin/phar.phar5.6 
update-alternatives --set phpize /usr/bin/phpize5.6
update-alternatives --set php-config /usr/bin/php-config5.6
service apache2 restart

switchTo7.2.sh

#!/bin/bash
a2dismod php5.6
a2enmod php7.2
update-alternatives --set php /usr/bin/php7.2
update-alternatives --set phar /usr/bin/phar7.2
update-alternatives --set phar.phar /usr/bin/phar.phar7.2 
update-alternatives --set phpize /usr/bin/phpize7.2
update-alternatives --set php-config /usr/bin/php-config7.2
service apache2 restart

Recordad que para que todo funcione habéis tenido que incluir los repositorios que tengan las distintas versiones de php. En mi caso incluí este:

sudo add-apt-repository ppa:ondrej/php

Y que tenéis que instalar todas las dependencias del proyecto en cuestión. En mi caso fueron estas (es un proyecto LAMP):

sudo apt-get install -y apache2 libapache2-mpm-itksudo apt-get install php php-mysql php-curl php-gd php-intl php-pear php-imagick php-imap php-memcache php-pspell php-recode php-tidy php-xmlrpc php7.2-xml  php-mbstring libapache2-mod-php

No es la solución ideal pero permite cambiar a una versión más «segura» en cualquier momento y asegurar que los proyectos siguen funcionando al margen de la versión actual de php.

En cualquier caso, seguro que surgen más problemas con el versionado de las librerías, ahí ya no queda más que rezar y esperar que todo siga funcionando «más o menos» como antes.