3
votes

I have an object Language, and I can add, delete and update languages from the admin page.

What I want to do, is to add a language switcher, I put this html/twig code:

 {% for language in languages %}         
      <li><a href="{{ path('evr_footer_switch_language',{'locale': language.code | lower }) }}">{{ language.language | capitalize }} ({{ language.code }})</a></li>
 {% endfor %}

And an action the route for the action is evr_footer_switch_language, the one I used in the switcher above:

 public function switchlanguageAction($locale = 'en') {

        $this->get('session')->set('_locale', $locale);
        $request = $this->getRequest();
       $request->setLocale($locale);
        return $this->redirect($request->headers->get('referer'));
    }

This is the route I defined for the action/controller switchlanguageAction()

evr_footer_switch_language:
    pattern: /language/switch/{locale}
    defaults: { _controller: EvrHomeBundle:Footer:switchlanguage, locale: en }

It seems to me very simple in principle, you click on the link of the language (got from the database), send the code of the language (exemple : 'fr', 'en', 'zh' etc...) to the action as a $locale variable, then set the Locale of the session/request to this value.

The problem is that none of this works, and the language is still 'EN' (default value).

Note According to the requirements of this project, The language can't be mentioned in the URL (like fr/articles, en/articles), but the same URL (/articles/) can show in different languages, this is why I didn't use the pre-defined slug (_locale).

Thanks

3

3 Answers

3
votes

While in search for some more details in order to write an answer I stumbled upon this Symfony cookbook entry: Making the Locale "Sticky" during a User's Session

I think that's exactly what you need ;)

3
votes

Symfony 2.6: I used the LocaleListener mentioned in "Making the Locale Sticky", but also had to use this to get things working properly:

/** from Controller
 *
 * @Route("/changeLanguage/{changeToLocale}", name="changeLanguage")
 *
 */
public function changeLanguageAction($changeToLocale){
    $this->get('request')->attributes->set('_locale', null);
    $this->get('session')->set('_locale', $changeToLocale);

    return $this->redirect($this->generateUrl('index'));
}
2
votes
public function onKernelRequest(GetResponseEvent $event)
{
    $request = $event->getRequest();
    if (!$request->hasPreviousSession()) {
        return;
    }

    // try to see if the locale has been set as a _locale routing parameter
    if ($locale = $request->query->get('swich_language')) {

        $request->getSession()->set('_locale', $locale);
        $routing = $this->router->match($request->getPathInfo());

        $route_params = array();

        foreach ($routing as $key => $value) {
            if($key[0] !== "_")
            {
                $route_params[$key] = $value;
            }
        }

        $parameters = \array_merge($route_params, array("_locale" => $locale));
        $url = $this->urlGenerator->generate($routing['_route'], $parameters);

        $response = new RedirectResponse($url);
        $event->setResponse($response);
    }
}

You can add as a kernel request and with querystring swich_language you can change it