6

I am trying to have a language switcher on my symfony 2.1 website.

I followed the official documentation, set the translation files but setting the locale with $request->setLocale('en_US'); doesn't seem to work. After some research, I found this question which provides a beginning of an answer with this listener technique.

However, I still don't manage to have it working, I'm not so sure about my listener declaration, is something wrong with it?

My controller:

public function englishAction(Request $request)
{
    $this->get('session')->set('_locale', 'en_US');
    return $this->redirect($request->headers->get('referer'));
}

Service declaration in config.yml:

services:
    my_listener:
        class:        "FK\MyWebsiteBundle\Listener\LocaleListener"

My routing:

homepage:
    pattern:  /{_locale}
    defaults: { _controller: FKMyWebsiteBundle:Default:index, _locale: en }
    requirements:
        _locale: en|fr|cn
about:
    pattern:  /{_locale}/about
    defaults: { _controller: FKMyWebsiteBundle:Default:about, _locale: en }
    requirements:
        _locale: en|fr|cn
Community
  • 1
  • 1
fkoessler
  • 6,932
  • 11
  • 60
  • 92
  • What are exactly your need? An example of use case? Maybe you doesn't need this listener – webda2l Oct 18 '12 at 10:46
  • @webda2l I simply want to allow the visitor to choose the website's language. The code in your answer isn't working but I guess I have to change my routes, I'll work some more on it.. – fkoessler Oct 19 '12 at 09:56
  • Am i setting up the listener properly? Will my LocaleListener will be called like this? – fkoessler Oct 20 '12 at 03:34
  • It seems not. I edited my answer. The best is to use a debugger (xdebug) to check the execution of your code. – webda2l Oct 22 '12 at 12:49

2 Answers2

9

The declaration of the LocaleListener in yml (inspired by the current declaration of the new LocaleListener: \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Resources\config\web.xml)

services:
    my_listener:
        class: "FK\MyWebsiteBundle\Listener\LocaleListener"
        arguments: [%locale%]
        tags:
            -  { name: kernel.event_subscriber }

Some snippets:

A language switcher in your template:

{% for locale in ['en', 'fr', 'cn'] %}
    <li {% if locale == app.request.locale %}class="active"{% endif %}>
        <a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale' : locale})) }}">{{ locale }}</a>
    </li>
{% endfor %}

A redirection with locale change from a controller:

$LocalizedUrl = $this->get('router')->generate(
    $request->attributes->get('_route'), 
    ['_locale' => $locale] + $request->attributes->get('_route_params')
);

return new \Symfony\Component\HttpFoundation\RedirectResponse($LocalizedUrl);
t j
  • 7,026
  • 12
  • 46
  • 66
webda2l
  • 6,686
  • 2
  • 26
  • 28
  • @webda2I Seems to be working real nice. Have to go now, will play more when I come back and will probably accept answer as it seems to be working fine :) I'm not sure to understand the code though :( – fkoessler Oct 23 '12 at 03:04
  • Works nice since I added the service properly in the services.xml. In my controller, I use: $this->get('session')->set('_locale', 'en_US'); return $this->redirect($request->headers->get('referer')); – fkoessler Oct 24 '12 at 02:10
  • Ok great. The basic declaration in YML must work but if you do the XML with service.xml, it's better. :) – webda2l Oct 24 '12 at 11:56
  • 1
    I followed the service declaration and everything, and I can see that the locale changes in the debug panel. However, translation is always done in the same language (english) which is not even the default language. Any tips on that? – Gabriel Theron Nov 09 '12 at 11:48
  • Maybe a problem with the read of your translations files? You are well in app_dev.php? You need clear cache otherwise. If you use DoctrineExtension Translatable feature with APC, you can see https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/translatable.md#overriding-translatable-locale – webda2l Nov 13 '12 at 09:54
1

You should get the translator instance linked to your symfony kernel container:

$this->container->get('translator')->setLocale('fr');
Arvid Vermote
  • 433
  • 5
  • 6