3

I would like to translate my website thanks to an link on the right top.

I found out that, since Symfony 2.1, the locale is not stored in the session anymore.

So, I followed this Symfony documentation: Making the Locale "Sticky" during a User's Session

...Bundle/Service/LocaleListener.php

class LocaleListener implements EventSubscriberInterface
{
    private $defaultLocale;

    public function __construct($defaultLocale)
    {
        $this->defaultLocale = $defaultLocale;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {

        $request = $event->getRequest();
        if (!$request->hasPreviousSession()) {
              return;
        }

        $locale = $request->attributes->get('_locale');
        var_dump($locale);

        if ($locale) {
             $request->getSession()->set('_locale', $locale);
        } else {
            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
        }
    }

    static public function getSubscribedEvents()
    {
        return array(
            // must be registered before the default Locale listener
            KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
        );
    }
}

...Bundle/Resources/config/services.yml

locale_listener:
    class: ..Bundle\Service\LocaleListener
    arguments: ["%kernel.default_locale%"]
    tags:
        - { name: kernel.event_subscriber }   

./app/config/config.yml

framework:
    translator:      { fallback: en }

And, I add two links to translate my website on the parent twig template, shown below (Symfony2 locale languages whole page event listener).

base.html.twig

<li><a href="{{-
                path(app.request.get('_route'),
                app.request.get('_route_params')|merge({'_locale' : 'fr'}))
            -}}">FR</a></li>
<li><a href="{{-
                path(app.request.get('_route'),
                app.request.get('_route_params')|merge({'_locale' : 'en'}))
            -}}">EN</a></li>

Problem and Question

When I click on one of these links, the parameter _locale is added.

For instance:

satisfaction?_locale=fr

So, the value of the _locale parameter is fr. Consequently, my website should be translated in french.

Nevertheless, that

var_dump($locale)

in the listener is displayed three times:

  1. null

  2. en

  3. null I don't understand why the _locale parameter is not found when it display null and why the en?

Community
  • 1
  • 1
Keysersoze
  • 184
  • 1
  • 12
  • `_locale` should be part of the url hierarchy like in `example.com/{_locale}/satisfaction ` not as a GET parameter (`example.com/satisfaction?_locale=fr`) – Peyman Mohamadpour Jan 01 '17 at 06:47

1 Answers1

2

With your listener, you will catch all request and subrequest that is not needed. This explain the three times apparition.

Try to add this following code to your onKernelRequest method:

if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) {
    return;
}

This will avoid subRequests and possibly resolve your problem.

Soullivaneuh
  • 3,553
  • 3
  • 37
  • 71
  • Ok, I added it on the top of my onKernelRequest method. Now, I've only two 'null' displayed.. But it not resolve my problem. – Keysersoze Aug 20 '14 at 09:24
  • In my listener, I use `$request->get('_locale')` instead of `$request->attributes->get('_locale')`, could you try it ? – Soullivaneuh Aug 20 '14 at 09:31
  • OK. Now, it displays "en" in every instance, dispite the url is `satisfaction?_locale=fr`... (by the way, thanks for your help) – Keysersoze Aug 20 '14 at 09:37
  • As indicated in the comment, your locale listener must be registered before the default Locale listener. In my Symfony 2.3 project, the default locale listner has a priority of 16. Try to change the priority of your listener, to 10 for exemple, or less... – Soullivaneuh Aug 20 '14 at 09:51
  • OK, I tried 10 & 1, it display "fr" in every instance. I do not understand why the listener don't retrieve the value of _locale parameter! – Keysersoze Aug 20 '14 at 10:57
  • 'fr' is the value you expected, no ? It's because the default locale listener do stuff before yours. – Soullivaneuh Aug 20 '14 at 12:24
  • I expect that the website is in French when I click on the link `FR` and in English when I click on `EN`. (Look at the twig template). – Keysersoze Aug 20 '14 at 12:25
  • Didn't understand, changing priority solved your problem or not ? – Soullivaneuh Aug 20 '14 at 14:19
  • Which Symfony version do you have ? – Soullivaneuh Aug 20 '14 at 14:45
  • 2
    Here my locale listener, if you want to check: http://pastebin.com/wqhYjmsC I added database locale storage feature on it, you can ignore this. – Soullivaneuh Aug 20 '14 at 14:49
  • Thank you a lot. I did not read correctly your first comment and I wrote `$request->getLocale()` instead of `$request->get('_locale');`. It works now. Thank you ;) – Keysersoze Aug 20 '14 at 15:04