I run a job every hour that can send an email to users. When the email is sent, it needs to be in the language set by the user (saved in the db). I can't figure out a way to set a different locale outside of a request context.
Here is what I would like to do:
def scheduled_task():
for user in users:
set_locale(user.locale)
print lazy_gettext(u"This text should be in your language")
You can also use method force_locale
from package flask.ext.babel
:
from flask.ext.babel import force_locale as babel_force_locale
english_version = _('Translate me')
with babel_force_locale('fr'):
french_version = _("Translate me")
Here's what its docstring say:
"""Temporarily overrides the currently selected locale.
Sometimes it is useful to switch the current locale to different one, do
some tasks and then revert back to the original one. For example, if the
user uses German on the web site, but you want to send them an email in
English, you can use this function as a context manager::
with force_locale('en_US'):
send_email(gettext('Hello!'), ...)
:param locale: The locale to temporary switch to (ex: 'en_US').
"""
One way to do it is to set up dummy request context:
with app.request_context({'wsgi.url_scheme': "", 'SERVER_PORT': "", 'SERVER_NAME': "", 'REQUEST_METHOD': ""}):
from flask import g
from flask_babel import refresh
# set your user class with locale info to Flask proxy
g.user = user
# refreshing the locale and timezeone
refresh()
print lazy_gettext(u"This text should be in your language")
Flask-Babel gets its locale settings by calling @babel.localeselector. My localeselector looks something like this:
@babel.localeselector
def get_locale():
user = getattr(g, 'user', None)
if user is not None and user.locale:
return user.locale
return en_GB
Now, every time you change your g.user you should call refresh() to refresh Flask-Babel locale settings
@ZeWaren 's answer is great if you are using Flask-Babel, but if you are using Flask-BabelEx, there is no force_locale
method.
This is a solution for Flask-BabelEx:
app = Flask(__name__.split('.')[0]) # See http://flask.pocoo.org/docs/0.11/api/#application-object
with app.test_request_context() as ctx:
ctx.babel_locale = Locale.parse(lang)
print _("Hello world")
Note the .split()
is important if you are using blueprints. I struggled for a couple of hours because the app
object was created with a root_path of 'app.main', which would make Babel look for translation files in 'app.main.translations' while they were in 'app.translations'. And it would silently fall back to NullTranslations
i.e. not translating.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With