我正在使用烧瓶,pybabel用于i18n。有时我需要向用户发送电子邮件。我想用他们自己的语言发送电子邮件。语言代码存储在数据库中,因此问题是使用正确的语言翻译模板。这是我的发送功能的一部分:
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)
模板的例子:
{{ _('Hi {name}. How are you?').format(user.name) }}
我需要的只是set_langauge(lang)
,我可以在每个模板渲染之前调用它。我该怎么办?
感谢。
答案 0 :(得分:4)
我有电子邮件的下一个render_template
功能:
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)
因此,如果您只需要在请求上下文中更改语言,请使用下一个代码(请参阅get_locale
):
def set_langauge(lang)
ctx = _request_ctx_stack.top
ctx.babel_locale = Locale.parse(lang)
答案 1 :(得分:4)
感谢@tbicr,我最终得到了这个解决方案。
在我的app.py中,我有set_locale
函数:
from flask import _request_ctx_stack as ctx_stack
# ...
def set_locale(lang):
ctx = ctx_stack.top
ctx.babel_locale = lang
# ...
我在渲染电子邮件模板之前调用它。
问题是我需要同时向不同语言的许多用户发送电子邮件:
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)
当我第一次调用set_locale
时,缓存了语言环境的值,并且使用第一个用户的语言呈现了所有电子邮件。
解决方案是每次flaskext.babel.refresh
set_locale