Search code examples
pythonflaskinternationalizationgettextpython-babel

python gettext different languages at same time


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.


Solution

  • 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)