Sonataadminbundle: add a language switcher

Created on 19 Dec 2012  路  8Comments  路  Source: sonata-project/SonataAdminBundle

basically just a way to switch the session to a different language. maybe use LuneticsLocaleBundle

Most helpful comment

I followed @rande suggestion and created language switcher this way (using sf4 and autowiring):

  1. Create LocaleSubscriber and UserLocaleSubscriber as explained here.
  2. Create controller to handle locale switch in src/Controller/LocaleController.php:
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;

final class LocaleController
{
    /**
    * @Route("/locale/{locale}", name="locale")
    */
    public function index(Request $request, string $locale): RedirectResponse
    {
        $request->getSession()->set('_locale', $locale);
        return new RedirectResponse($request->headers->get('referer', '/'));
    }
}
  1. Override standard_layout.html.twig:
  2. Create src/templates/bundles/SonataAdminBundle/standard_layout.html.twig:
{% extends '@!SonataAdmin/standard_layout.html.twig' %}

{% block sonata_top_nav_menu %}
    {{ parent() }}
    <div class="navbar-custom-menu">
        <ul class="nav navbar-nav">
            {% block sonata_top_nav_menu_locale_block %}
                <li class="dropdown">
                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                        <i class="fa fa-flag fa-fw" aria-hidden="true"></i>
                        <i class="fa fa-caret-down" aria-hidden="true"></i>
                    </a>
                    <div class="dropdown-menu multi-column dropdown-add">
                        <div class="container-fluid">
                            <div class="row">
                                <ul class="dropdown-menu">
                                    <li role="presentation" class="dropdown-header">
                                        <i class="fa fa-language"></i>
                                        {{ 'languages_title'|trans({}, 'SonataAdminBundle') }}
                                    </li>
                                    {% for locale in available_locales|split('|') %}
                                    <li role="presentation" class="{{ app.request.locale == locale ? 'active' : '' }}">
                                        <a role="menuitem" tabindex="-1" href="{{ path('locale', {'locale': locale}) }}">{{ locale|language|capitalize }}</a>
                                    </li>
                                    {% endfor %}
                                </ul>
                            </div>
                        </div>
                    </div>
                </li>
            {% endblock %}
        </ul>
    </div>
{% endblock %}
  1. Update your config to make it work:
  2. Create twig available_locales parameter by adding this to /config/packages/twig.yaml:
twig:
    ...
    globals:
        available_locales: '%app.locales%'
  • Make sure app.locales is defined in config/services.yaml:
parameters:
    ...
    app.locales: en|fr
  • Install Sonata Intl Bundle that is needed by our template to convert locale to language name with twig locale helper: composer require sonata-project/intl-bundle
    Alternatively, you can replace {{ locale|language|capitalize }} by {{ locale }} in template if you don't need locale switcher to display language.
  • That's all! You should now have working language switcher in top right corner of your admin :)

All 8 comments

@lsmith77 the top right corner template can be tweaked so you can include the language switcher here.

indeed. got it to work like that.

can you post your solution here @lsmith77 ?

I followed @rande suggestion and created language switcher this way (using sf4 and autowiring):

  1. Create LocaleSubscriber and UserLocaleSubscriber as explained here.
  2. Create controller to handle locale switch in src/Controller/LocaleController.php:
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;

final class LocaleController
{
    /**
    * @Route("/locale/{locale}", name="locale")
    */
    public function index(Request $request, string $locale): RedirectResponse
    {
        $request->getSession()->set('_locale', $locale);
        return new RedirectResponse($request->headers->get('referer', '/'));
    }
}
  1. Override standard_layout.html.twig:
  2. Create src/templates/bundles/SonataAdminBundle/standard_layout.html.twig:
{% extends '@!SonataAdmin/standard_layout.html.twig' %}

{% block sonata_top_nav_menu %}
    {{ parent() }}
    <div class="navbar-custom-menu">
        <ul class="nav navbar-nav">
            {% block sonata_top_nav_menu_locale_block %}
                <li class="dropdown">
                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                        <i class="fa fa-flag fa-fw" aria-hidden="true"></i>
                        <i class="fa fa-caret-down" aria-hidden="true"></i>
                    </a>
                    <div class="dropdown-menu multi-column dropdown-add">
                        <div class="container-fluid">
                            <div class="row">
                                <ul class="dropdown-menu">
                                    <li role="presentation" class="dropdown-header">
                                        <i class="fa fa-language"></i>
                                        {{ 'languages_title'|trans({}, 'SonataAdminBundle') }}
                                    </li>
                                    {% for locale in available_locales|split('|') %}
                                    <li role="presentation" class="{{ app.request.locale == locale ? 'active' : '' }}">
                                        <a role="menuitem" tabindex="-1" href="{{ path('locale', {'locale': locale}) }}">{{ locale|language|capitalize }}</a>
                                    </li>
                                    {% endfor %}
                                </ul>
                            </div>
                        </div>
                    </div>
                </li>
            {% endblock %}
        </ul>
    </div>
{% endblock %}
  1. Update your config to make it work:
  2. Create twig available_locales parameter by adding this to /config/packages/twig.yaml:
twig:
    ...
    globals:
        available_locales: '%app.locales%'
  • Make sure app.locales is defined in config/services.yaml:
parameters:
    ...
    app.locales: en|fr
  • Install Sonata Intl Bundle that is needed by our template to convert locale to language name with twig locale helper: composer require sonata-project/intl-bundle
    Alternatively, you can replace {{ locale|language|capitalize }} by {{ locale }} in template if you don't need locale switcher to display language.
  • That's all! You should now have working language switcher in top right corner of your admin :)

@jo66 would you like to provide a PR and add this to documentation?

@kunicmarko20 done! Here is the link.

Global locale switcher is now implemented in SonataTranslationBundle, see doc.

Thank you @jo66!

Was this page helpful?
0 / 5 - 0 ratings