9

Now I'm developing a project, which should support two languages: English, as default, and Russian. It's pretty easy to do, using HTTP_ACCEPT_LANGUAGE header, the code is bellow:

babel = Babel(app)

@babel.localeselector
def get_locale():
    return request.accept_languages.best_match(app.config["LANGUAGES"].keys())

Languages are hardcoded in application config file:

LANGUAGES = {
    'en': 'English',
    'ru': 'Russian'
}

But I also want to add a button, like Switch language to English. What is the best practice to realise it?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Sergey Potekhin
  • 621
  • 1
  • 11
  • 27

1 Answers1

25

This is the solution I came across:

First you set a route that will handle the language change and will store the selected language on the session:

@app.route('/language/<language>')
def set_language(language=None):
    session['language'] = language
    return redirect(url_for('index'))

Secondly, you have to modify a little the code you have to get the selected language from the session:

@babel.localeselector
def get_locale():
    # if the user has set up the language manually it will be stored in the session,
    # so we use the locale from the user settings
    try:
        language = session['language']
    except KeyError:
        language = None
    if language is not None:
        return language
    return request.accept_languages.best_match(app.config['LANGUAGES'].keys())

You have also to be able to access the CURRENT_LANGUAGE from the templates, so you can inject it:

@app.context_processor
    def inject_conf_var():
        return dict(
                    AVAILABLE_LANGUAGES=app.config['LANGUAGES'],
                    CURRENT_LANGUAGE=session.get('language',request.accept_languages.best_match(app.config['LANGUAGES'].keys())))

Finally, on the template you can choose the the language you want:

{% for language in AVAILABLE_LANGUAGES.items() %}
     {% if CURRENT_LANGUAGE == language[0] %}
         {{ language[1] }}
     {% else %}
         <a href="{{ url_for('set_language', language=language[0]) }}" >{{ language[1] }}</a>
     {%  endif %}
{% endfor %}

Application config.py includes the following constant:

LANGUAGES = {
  'en': 'English',
  'es': 'Spanish'
}

Hope this helps!

René Fernández
  • 612
  • 8
  • 11
  • Where did you create the AVAILABLE_LANGUAGES? Is it just LANGUAGES that you refer to? – Salviati Jul 27 '18 at 07:21
  • And also, I found that the app config has to be refreshed when you change the default language of app. Default language will be automatically set once you launch the app, and it will store in cache. – JunKim Sep 19 '18 at 15:32
  • Hi, I just added more details about the LANGUAGES and AVAILABLE_LANGUAGES constants. Check the inject_conf_var and config.py parts. Cheers. – René Fernández Sep 21 '18 at 10:02