Vous souhaitez faire une application Symfony 2 multilingue ?
Ce n’est pas difficile, il suffit de modifier 4 fichiers.
PS: Je part du principe que vous avez déjà fait vos fichiers de traduction. Si ce n’est pas le cas, rendez-vous dans le Book Symfony 2 !
Premièrement, il faut créer un listener.
Créez le fichier VotreBundle/EventListener/LocalListener.php et collez-y ceci:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php namespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class LocaleListener implements EventSubscriberInterface { private $defaultLocale; public function __construct($defaultLocale = 'en') { $this->defaultLocale = $defaultLocale; } public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); if (!$request->hasPreviousSession()) { return; } // On essaie de voir si la locale a été fixée dans le paramètre de routing _locale if ($locale = $request->attributes->get('_locale')) { $request->getSession()->set('_locale', $locale); } else { // Si aucune locale n'a été fixée explicitement dans la requête, on utilise celle de la session $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); } } public static function getSubscribedEvents() { return array( // Doit être enregistré avant le Locale listener par défaut KernelEvents::REQUEST => array(array('onKernelRequest', 17)), ); } } |
Ensuite, dans VotreBundle/Resources/config/services.yml (je travaille en YAML, je vous laisse adapter à vos besoins si vous êtes en XML ou autre), ajouter les lignes suivantes:
1 2 3 4 5 |
votrebundle.locale_listener: class: VotreBundle\EventListener\LocaleListener arguments: ["%kernel.default_locale%"] tags: - { name: kernel.event_subscriber } |
Il nous faut un contrôleur pour demander le changement de langue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/** * Change the locale for the current user * * @param String $language * @return array * * @Route("/setlocale/{language}", name="setlocale") * @Template() */ public function setLocaleAction($language = null) { if($language != null) { // On enregistre la langue en session $this->get('session')->set('_locale', $language); } // on tente de rediriger vers la page d'origine $url = $this->container->get('request')->headers->get('referer'); if(empty($url)) { $url = $this->container->get('router')->generate('index'); } return new RedirectResponse($url); } |
Et enfin, dans votre twig, mettez des petits boutons avec, par exemple, un drapeau:
1 2 |
<a href="{{ path('setlocale', {'language': 'fr'}) }}">FR</a> <a href="{{ path('setlocale', {'language': 'en'}) }}">EN</a> |
And Voila ! 🙂
Bonjour,
Il manque une virgule dans l’anotation de la fonction du controller (ligne 7), remplacer par :
@Route(“/setlocale/{language}”, name=”setlocale”)
En effet, c’est corrigé, merci !
Salut, merci pour ton code 🙂
Quand je l’utilise moi j’ai un
ReflectionException in RegisterListenersPass.php line 101: Class Fw\FollowBundle\EventListener\LocaleListener does not exist
J’ai trouvé un post sur la même chose sur stackoverflow, mais pas de réponse. (je précise que, contrairement a la personne qui a eu le pb sur stack, je n’ai pas fait d’erreur sur le namespace)
As-tu eu le pb ? merci 🙂
Et bien en effet, c’est mon phpstorm qui a fait une mauvaise bidouille … j’aurais du vérifier ça avant de poster un msg.
Merci 🙂
Pas de soucis 😉
Tanx <3
Bonjour,Je me permets de vous contacter suite à votre tutoriel : Changer la langue dans Symfony 2.En effet, j’ai appliqué à la lettre ce que vous aviez fait, mais je suis tombé sur une erreur que je ne comprend pas et que je n’arrive pas à corriger.Ci-dessous mon erreur :InvalidArgumentException in RegisterListenerPass.php line 103:Service “front_bundle.locale_listener” must implement interface “Symfony\Component\EventDispatcher\EventSubscriberInterface”.Mon fichier : services.ymlservices: front_bundle.locale_listener: class: FrontBundle\EventListener\LocaleListenere arguments: [“%kernel.default_locale%”] tags: – { name: kermel.event_subscriber }Avez-vous une idée sur ce type d’erreur? Si quelqu’un l’a déjà traité. Je ne trouve rien sur le net.Merci par avance !
Bonjour 🙂
Vous avez écrit:
Le problème ne viendrait pas du
class: FrontBundle\EventListener\LocaleListenere
au lieu de
class: FrontBundle\EventListener\LocaleListener
(Un “e” en trop dans “LocaleListener” à la fin) ?Merci d’avoir pris le temps de me répondre.
Oui justement c’était une erreur de saisie. J’ai corrigé mais toujours l’erreur s’affiche.
C’est bon j’ai trouvé la solution au problème. Il suffit de rajouter le namespace de mon bundle (FrontBundle) dans les fichiers: services.yml et LocaleListener.php.
Merci bcp ! A bientôt!
et comment on rajoute le namespace de bundle dans le services.yml??? merci
Salut Tom! Est-ce que vous pouvez détailler comment rajouter le namespace dans les fichiers: services.yml et LocaleListener.php?
Merci d’avance mon ami!
Bonjour, merci pour ce tuto !
Je voulais savoir s’il était possible de détecter la locale de l’utilisateur et de la charger, tout en laissant la possibilité de choisir la langue via une liste déroulante ?
Pour le moment j’ai mis en place une liste déroulante qui fonctionne (juste français / anglais pour le moment) cependant quand je me rends sur la page d’accueil, c’est automatiquement la langue anglaise qui est chargée !
Savez-vous comment faire ? Merci d’avance !
Bonjour,J’ai un problème, lorsque je clique sur mon EN ou FR j’obtiens cette erreur:You have requested a non-existent service “request”. Did you mean one of these: “data_collector.request”, “fos_rest.request.param_fetcher”, “fos_rest.request.param_fetcher.reader”, “monolog.logger.request”, “request_stack”, “router.request_context”, “validate_request_listener”?et correspond à la ligne:$url = $this->container->get(‘request’)->headers->get(‘referer’);Merci d’avance pour votre réponse.