3

i18nにはフラスコ、pybabelを使用しています。ユーザーにメールを送信する必要がある場合があります。そして、自分の言語でメールを送りたいです。言語コードはデータベースに保存されるため、問題はテンプレートを適切な言語に翻訳することです。これが私の送信機能の一部です:

            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)各テンプレートがレンダリングされる前に呼び出すことができるようなものだけです。どうすればいいですか?

ありがとう。

4

2 に答える 2

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

于 2013-06-30T17:03:18.777 に答える
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)
于 2013-06-29T15:15:28.970 に答える