4

On my website use Flask + Jinja2, and Flask-Babel for translation. The site has two languages (depending on the URL), and I'd want to add a link to switch between them. To do this correctly I need to get the name of the current locale, but I didn't find such function in the docs. Does it exist at all?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
aplavin
  • 2,199
  • 5
  • 32
  • 53

3 Answers3

7

Other answers say that you must implement the babel's get_locale() function and that you should add it to Jinja2 globals, but they don't say how. So, what I did is:

I implemented the get_locale() function as follows:

from flask import request, current_app

@babel.localeselector
def get_locale():
    try:
        return request.accept_languages.best_match(current_app.config['LANGUAGES'])
    except RuntimeError:  # Working outside of request context. E.g. a background task
        return current_app.config['BABEL_DEFAULT_LOCALE']

Then, I added the following line at my Flask app definition:

app.jinja_env.globals['get_locale'] = get_locale

Now you can call get_locale() from the templates.

Caumons
  • 9,341
  • 14
  • 68
  • 82
5

Finally, I used this solution: add get_locale function, which should be defined anyway, to Jinja2 globals, and then call it in template like any other function.

aplavin
  • 2,199
  • 5
  • 32
  • 53
  • 2
    How did you add to jinja2 globals? I've tried doing e=Environment, e.globals = {'get_locale':get_locale} – 8oh8 Mar 21 '17 at 02:00
1

You are responsible to store the user's locale in your session on database. Flask-babel will not do this for you, so you should implement get_locale method for flask-babel to be able to find your user's locale.

This is an example of get_locale from flask-babel documentation:

from flask import g, request

@babel.localeselector
def get_locale():
    # if a user is logged in, use the locale from the user settings
    user = getattr(g, 'user', None)
    if user is not None:
        return user.locale
    # otherwise try to guess the language from the user accept
    # header the browser transmits.  We support de/fr/en in this
    # example.  The best match wins.
    return request.accept_languages.best_match(['de', 'fr', 'en'])
MostafaR
  • 3,547
  • 1
  • 17
  • 24
  • 2
    Yes, I've implemented such get_locale function, it returns a locale depending on the URL. But how to get active request locale in a Jinja template? – aplavin May 05 '13 at 12:02