2013-06-29 4 views
3

저는 플라스크를 사용하고 있습니다 .1818에 pybabel을 사용하고 있습니다. 때로는 사용자에게 이메일을 보내야합니다. 그리고 나는 그들의 언어로 이메일을 보내고 싶다. 언어 코드는 데이터베이스에 저장되므로 문제는 올바른 언어로 템플릿을 번역하는 것입니다. 템플릿의python gettext 동시에 다른 언어

  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) 같은 것입니다 여기에 내 보내는 기능의 일부입니다. 내가 어떻게 해?

감사합니다. 나는이 종료 @tbicr하는

def set_langauge(lang) 
    ctx = _request_ctx_stack.top 
    ctx.babel_locale = Locale.parse(lang) 

답변

4

나는 이메일에 대한 다음 render_template 기능이 이 솔루션으로 내 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 
# ... 

을 나는 이메일 템플릿을 렌더링하기 전에 호출합니다.

문제 I가 동시에 서로 다른 언어로 많은 사용자에게 이메일을 보낼 필요가 있었다 :

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 처음 로케일의 값은 캐시 된 모든 이메일은 언어로 표현 된를 호출 할 때 첫 번째 사용자의

set_locale

다음에 매번 flaskext.babel.refresh을 호출하면 해결됩니다.
4

감사 : 그래서

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 참조)