Internationalisation — Formation Symfony 7

Dans ce chapitre nous allons voir comment gérer l’internationalisation d’une application web avec Symfony.

Traduction de chaîne

Pour les chaînes présentes dans le code source il est possible de les traduire de différentes manières en fonction de la situation.

<!-- Via un filtre -->
{{ 'Welcome' | trans  }}

<!-- Via un tag -->
{% trans %}Welcome{% endtrans %}

Dans les controllers et les services il est possible d’utiliser le service de traduction pour obtenir la version traduite d’une chaîne.

use Symfony\Contracts\Translation\TranslatorInterface;

public function index(TranslatorInterface $translator): Response
{
    $translated = $translator->trans('Welcome');
}

Ensuite, les traductions de nos chaînes seront placées dans le dossier translations au format yaml. Ce dossier, et la locale à utiliser par défaut sont configurés dans le fichier de configuration translation.yaml.

# messages.fr.yaml
welcome: Bienvenue

Pour des traductions plus complexe (genre et pluralisation) il est possible d’utiliser le format ICU pour les messages.

Sélection de la langue

Maintenant que nous avons nos traduction il faut pouvoir passer d’une traduction à l’autre. Cela peut se faire de plusieurs manières.

Via l’URL

Le cas classique est de préfixer nos URL avec la langue choisie par l’utilisateur.

# config/routes.yaml
controllers:  
    prefix: "{_locale}"  
    requirements:  
        _locale: en|fr|de  
    resource:  
        path: ../src/Controller/  
        namespace: App\Controller  
    type: attribute

L’attribut _locale sera automatiquement pris en compte par le système de traduction qui appliquera la locale associée à ce paramètre. Vous pouvez utiliser cet attribut n’importe où dans votre application.

Via une préférence utilisateur

Une autre possibilité est d’utiliser une préférence utilisateur pour définir la langue de l’interface. Dans ce cas là, il sera possible d’utiliser un écouteur d’évènement et d’utiliser le service LocaleSwitcher pour changer la locale du site.

<?php

namespace App\EventListener;

use App\Entity\User;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Translation\LocaleSwitcher;

final class UserLocaleListener
{

    public function __construct(
        private readonly Security $security,
        private readonly LocaleSwitcher $localeSwitcher
    ){

    }

    #[AsEventListener(event: KernelEvents::REQUEST)]
    public function onKernelRequest(RequestEvent $event): void
    {
        $user = $this->security->getUser();
        if ($user && $user instanceof User) {
            $this->localeSwitcher->setLocale($user->getLocale());
        }
    }
}

Traduction des entités

En revanche, Symfony n’intègre pas d’outil interne pour la traduction des champs de votre base de données. Cependant il est possible d’utiliser le module DoctrineExtension qui permet l’ajout de comportements supplémentaire. Pour simplifier son intégration au sein de Symfony on pourra utiliser le bundle StofDoctrineExtensionsBundle

composer require stof/doctrine-extensions-bundle

Vous pourrez ensuite suivre les instructions de la documentation pour activer l’extension gedmo_translatable.