marcuse
marcuse

Reputation: 3999

Manually switch _locale in symfony 4

I'm absolutely stuck in getting a solution to manually switch the _locale variable in Symfony 4.

I followed these steps, but now I have absolutely no idea how to make a simple switch button in the nav section. I also took a look a this question, but this seems to be an older Symfony version..

Can anyone please help me climb out of this dark hole and explain to me how I can integrate a simple _locale switch button, or at least point me in the right direction?

Upvotes: 1

Views: 3474

Answers (3)

Mecanik
Mecanik

Reputation: 1051

As of latest Symfony (5.3.9), I strongly suggest one follows the documentation:

https://symfony.com/doc/current/the-fast-track/en/28-intl.html

Towards the end, do a bit of tweaking to generate a nice dropdown menu correctly based on your available languages:

<ul class="navbar-nav me-auto mb-2 mb-md-0">
    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false" id="locales">
            <i class="fa fa-globe" aria-hidden="true"></i>
            {{ app.request.locale|locale_name(app.request.locale)|u.title }}
        </a>
        <ul class="dropdown-menu" aria-labelledby="locales">
            {% for locale in locales|split('|') %}
                <li>
                    <a {% if app.request.locale == locale %} 
                        class="dropdown-item active" 
                    {% else %} 
                        class="dropdown-item" 
                    {% endif %} 
                        href="{{ path(app.request.get('_route', 'app_index'), app.request.get('_route_params', [])|merge({_locale: locale})) }}">
                        {{ locale|locale_name(locale)|u.title }}
                    </a>
                </li>
            {% endfor %}
        </ul>
    </li>
</ul>

PS: The above is using Bootstrap 5.

Upvotes: 2

Semih
Semih

Reputation: 1

Here is what works for me on latest symfony 4 version

services.yaml:

parameters:
    locale: 'en'
    app_locales: en|fr

twig:
    globals:
        locales: '%app_locales%'

locale template:

{# project/templates/_locale_switcher.html.twig #}

{% set route = app.request.attributes.get('_route') %}
{% set route_params = app.request.attributes.get('_route_params') %}
{% set params = route_params|merge(app.request.query.all) %}

{# You may want to not print a flag/link for current view, the "if" here let
you handle it #}

{% for locale in locales|split('|') %}
    {% if locale != app.request.locale %}
        <li>
            <a href="{{ path(route, params|merge({ _locale: locale })) }}">
                <img src="{{ asset('img/flags/' ~ locale ~ '.jpg') }}" alt="{{ locale }}">
            </a>
        </li>
    {% endif %}
{% endfor %}

Upvotes: 0

marcuse
marcuse

Reputation: 3999

The answer is slightly different from this answer which is not applicable in Symfony 4. Start with editing the services.yaml file in the config directory.

{# project/config/services.yaml}

# ...
parameters:
    # ...
    app_locales: [nl_NL, en_EN]

twig:
    # ...
    globals:
        locales: %app_locales%
        # ...

Then add a template to integrate the switch button somewhere in your base template.

{# project/templates/_locale_switcher.html.twig #}

{% set route = app.request.attributes.get('_route') %}
{% set route_params = app.request.attributes.get('_route_params') %}
{% set params = route_params|merge(app.request.query.all) %}

{# You may want to not print a flag/link for current view, the "if" here let 
you handle it #}

{% for locale in locales if locale != app.request.locale %}

    <li>
        <a href="{{ path(route, params|merge({ _locale: locale })) }}">
            <img src="{{ asset('img/flags/' ~ locale ~ '.jpg') }}" alt="{{ 
locale }}">
        </a>
    </li>

{% endfor %}

And finally integrate this brandnew template in your base template.

{# project/templates/base.html.twig #}

{% include '_locale_switcher.html.twig' %}

EDIT for Symfony 4.3.4+

As per the answer of Charles beneath, the locales value in services.yaml file should be inserted with quotes to avoid an unvalid YAML error:

{# project/config/services.yaml}

# ...
parameters:
    # ...
    app_locales: [nl_NL, en_EN]

twig:
    # ...
    globals:
        locales: "%app_locales%"
        # ... 

Upvotes: 6

Related Questions