Dennis Dennis - 7 months ago 11
PHP Question

Symfony2 locale ignored for base twig template

Situation



I'm setting locale on a listener listening on
kernel.request
like this:

<?php
// ...
class LocaleListener
{
//...
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$event->isMasterRequest()) {
return;
}

// [...] some logic to get $locale
$request->setLocale($locale);
}
}
?>


Then, I have two twig templates, a base and a base-extending-template. Base template (
base.html.twig
):

<html>
<body>
{{ 'some.translation'|trans({}, 'messages') }}

{% block body %}{% endblock %}
</body>
</html>


And the base-extending-template (
profile.html.twig
):

{% extends '::base.html.twig' %}

{% block body %}
{{ 'some.translation'|trans({}, 'messages') }}
{% endblock %}


The Controller of the route will render profile.html.twig:

<?php
// ...
class SomeController extends Controller
{
//...
public function someAction()
{
return $this->render('::profile.html.twig');
}
}
?>


Nothing special, all very simple...

Problem



The rendered template extending the base (
profile.html.twig
) is using the locale for the translation set in the listener. Unfortunately the base template (
base.html.twig
) IS NOT. Even when I dump
{{ dump(app.request.locale) }}
on the base template, it shows the correct locale set in the listener...

What do I miss?




Edit



Oh, and I'm using Symfony v2.7.11.

Answer

Working solution: Created the LocaleListener exactly like documented here (hint by Yoshi).

Addendum: I wanted the locale stored in User's entity to be used, so I had to create a InteractiveLoginListener (class file). As of version 1.3.6, there's (like 2.0-alpha, even though not documented) an event called security.interactive_login which had to be injected:

app.interactive_login_listener:
    class: AppBundle\EventListener\Security\InteractiveLoginListener
    arguments: ['@fos_user.user_manager', '@session']
    tags:
        - { name: 'kernel.event_listener', event: 'security.interactive_login', method: 'onSecurityInteractiveLogin' }