python gettext different languages at same time
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)
Thanks to @tbicr I ended up with this solution.
In my app.py I have set_locale
function:
from flask import _request_ctx_stack as ctx_stack# ...def set_locale(lang): ctx = ctx_stack.top ctx.babel_locale = lang# ...
and I call it before rendering email template.
The problem was I need to send emails to many users with different languages at the same time:
with app.test_request_context(): with mail.connect() as conn: for user in users: set_locale(user.get_lang()) subject = _(u'Best works').format(get_month_display(month)) body = render_template('emails/best_works.eml' recipients = [user.email] msg = Message(subject, html=body, recipients=recipients) conn.send(msg)
and when I call set_locale
first time the value of locale was cached and all emails were rendered with language of first user.
The solution is to call flaskext.babel.refresh
each time after set_locale