Reinherd
Reinherd

Reputation: 5504

Symfony2 locale isn't working properly

After reading documentation and looking for it with Google, I've to ask you.

I want to switch between 3 languages: ca_ES, es_ES and en_GB

So I did a controller like this:

/**
 * @Route("/canviar-idioma/{locale}", name="change_lang")
 * @Template()
 * 
 * @return array
 */
public function canviarIdiomaAction($locale){
    $request = $this->getRequest();
    if ($locale == 'cat'){
        $this->get('translator')->setLocale('ca_ES');
        return new Response('ca');
    } else if ($locale == 'es'){
        $this->get('translator')->setLocale('es_ES');
        return new Response('es');
    } else if ($locale == 'eng'){
        $this->get('session')->set('_locale', 'en_GB');
        return new Response('en');
    }

    return new Response(null);
}

This controller is being called by ajax, when an user clicks a flag with the language. I receive the "ca" or "es" or "en" correctly, so controller is "working" somehow. As you can see, I've tried using it by session or getting the translator. Both ways same results.

But, I made this controller to check if my locale really changed:

/**
 * @Route("/quinlocaletinc", name="quinlocaletinc")
 * @Template()
 * 
 * @return array
 */
public function quinlocaletincAction(){
    $request = $this->getRequest();
    return new Response($request->getLocale());
}

And this locale ALWAYS gives "ca_ES" as it's the one defined in my parameters file:

locale: ca_ES

And my config.yml:

default_locale:  %locale%
translator:      { fallback: %locale% }

Upvotes: 0

Views: 812

Answers (2)

Pete Mitchell
Pete Mitchell

Reputation: 2879

You need to use the "special" _locale variable in the route, Symfony will then properly set the locale for your application.

You can read more about this in the documentation

Your route should look like this:

/**
 * @Route("/canviar-idioma/{_locale}", requirements={"_locale" = "ca_ES|es_ES|en_GB"}, name="change_lang")
 * @Template()
 * 
 * @return array
 */
public function canviarIdiomaAction() {
   $locale = $request->getLocale();

   // ...

Your second route will also need the parameter

/**
 * @Route("/quinlocaletinc/{_locale}", name="quinlocaletinc")
 * @Template()
 * 
 * @return array
 */
public function quinlocaletincAction() {
    $request = $this->getRequest();
    return new Response($request->getLocale());
}

A good convention is to prefix all routes with the locale rather than postfix

/**
 * @Route("/{_locale}/quinlocaletinc", name="quinlocaletinc")
 * @Template()
 * 
 * @return array
 */
public function quinlocaletincAction() {
    $request = $this->getRequest();
    return new Response($request->getLocale());
}

By using the _locale variable in Symfony, everything just "works" (i.e. if you visit /ca_ES/page all links on that page will include the right url).

Also when using the _locale parameter in your route, $this->get('translator')->setLocale('ca_ES'); is un-necessary as it will happen automatically.

Upvotes: 1

Nicolai Fröhlich
Nicolai Fröhlich

Reputation: 52513

Your annotation routing and Controller argument should be {_locale} and $_locale.

/**
 * @Route("/canviar-idioma/{_locale}", name="change_lang")
 * @Template()
 * 
 * @return array
 */
public function canviarIdiomaAction($_locale)
{
   // ...

Upvotes: 0

Related Questions