I'm using flask, pybabel for i18n. Sometimes I need to send emails to my users. And I want to send email in their own language. Language code stores in databases so the problem is to translate template with right language. Here is part of my sending function:
lang = user.get_lang()
subject = _('Subject')
for user in users:
if user.email:
body = render_template('emails/template.eml', user=user)
recipients = [user.email]
msg = Message(subject, html=body, recipients=recipients)
conn.send(msg)
And example of template:
{{ _('Hi {name}. How are you?').format(user.name) }}
All I need is something like set_langauge(lang)
which I can call before each template render. How can I do it?
Thanks.
I have next render_template
function for emails:
def render_template(template_name_or_list, **context):
# get request context
ctx = _request_ctx_stack.top
# check request context
# if function called without request context
# then call with `test_tequest_context`
# this because I send email from celery tasks
if ctx is None:
with current_app.test_request_context():
return render_template(template_name_or_list, **context)
# I have specific locale detection (from url)
# and also use `lang` variable in template for `url_for` links
# so you can just pass language parameter without context parameter
# and always set `babel_locate` with passed language
locale = getattr(ctx, 'babel_locale', None)
if locale is None:
ctx.babel_locale = Locale.parse(context['lang'])
# render template without additinals context processor
# because I don't need this context for emails
# (compare with default flask `render_template` function)
return _render(ctx.app.jinja_env.get_or_select_template(
template_name_or_list), context, ctx.app)
So if you need just change language in request context use next code (see get_locale
):
def set_langauge(lang)
ctx = _request_ctx_stack.top
ctx.babel_locale = Locale.parse(lang)