Vitali Ponomar Vitali Ponomar - 1 month ago 6
Python Question

How to use Pyramid i18n outside of views and templates?

Pyramid documentation shows us how to use i18n inside views (and templates as well). But how to does one use it outside of views and templates where we have no access to current

request
(for example, in
forms
and
models
)?

@Michael said to pass
request
to models and forms. But is it right? I mean if form fields defines before
__init__()
method calls, the same with models. They don't see any parameters from views...

In Pylons we could simply use
get_lang()
and
set_lang()
and define preferable language in parent controller and then use
ugettext()
and
ungettext()
in any place we want without calling it from
request
directly every possible time (in views).

How to do that in Pyramid? Note that the language must be set from user's settings (session, cookies, db, etc).

Answer

My solution is to create the form class when it's needed with localizer as parameter. For example

forms.py

class FormFactory(object):

    def __init__(self, localizer):
        self.localizer = localizer
        _ = self.localizer
        self.required_msg = _(u'This field is required.')
        self.invalid_email_msg = _(u'Invalid email address.')
        self.password_not_match_msg = _(u'Password must match')

    def make_contact_form(self):
        _ = self.localizer
        class ContactForm(Form):
            email = TextField(_(u'Email address'), [
                validators.Required(self.required_msg),
                validators.Email(self.invalid_email_msg)
            ])
            content = TextAreaField(_(u'Content'), [
                validators.Required(self.required_msg)
            ])
        return ContactForm

When you need to use the form

@view_config(route_name='front_pages.contact_us',
             renderer='myweb:templates/front_pages/contact_us.genshi')
def contact_us(request):
    """Display contact us form or send mail

    """
    _ = get_localizer(request)

    factory = FormFactory(_)
    ContactForm = factory.make_contact_form()
    form = ContactForm(request.params)
    return dict(form=form)

As you can see, we get the localizer in the view, and pass it to the FormFactory, then create a form with that factory. By doing that, all messages in the form was replaced with current locale language.

Likewise, you can do the same with model.

Comments