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.