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?
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!