Alexandre Bourget

geek joy

Pyramid and Mako: how to do i18n the Pylons way

January 13, 2011 at 09:07 PM

In reply to this post about the Pylons way to do translation using Pyramid, here is my code snippet so that you don't need to put the request object in, each time you want to translate something:

def main(...):

or wherever the following add_renderer_globals will be.

Then add, let's say in

from pyramid.i18n import get_localizer, TranslationStringFactory

def add_renderer_globals(event):
    request = event.request
    event['_'] = request.translate
    event['localizer'] = request.localizer

tsf = TranslationStringFactory('YOUR_GETTEXT_DOMAIN')

def add_localizer(event):
    request = event.request
    localizer = get_localizer(request)
    def auto_translate(string):
        return localizer.translate(tsf(string))
    request.localizer = localizer
    request.translate = auto_translate

Now, in your Mako template, you'll be able to use the simple ${_(u"Translate this string please")} without having to specify the request explicitly, as it's enclosed in this request's "_" function. localizer will also be available for plural forms and fancy stuff.

This version will also allow you to use translation in your view code, using something like:

def my_view(request):
    _ = request.translate
    request.session.flash(_("Welcome home"))

Now for all that to work, you'll need to:

(env)$ pip install Babel

first, and also run these commands in your project's directory:

(env)$ python extract_messages
(env)$ python init_catalog -l en
(env)$ python init_catalog -l fr
(env)$ python init_catalog -l es
(env)$ python init_catalog -l it
(env)$ python update_catalog
(env)$ python compile_catalog

... for the langauges you need. Note that the sub-directory of your project is locale/ in Pyramid, and not i18n/ as it was in Pylons. You'll notice that in the default setup.cfg of a Pyramid project.

Lastly, you'll want to have your Mako files extracted when you run extract_messages, so add these to your (yes, you read me right, in so that Babel can use it when invoking it's commands):

    message_extractors = {'yourpackage': [
            ('**.py', 'python', None),
            ('templates/**.html', 'mako', None),
            ('templates/**.mako', 'mako', None),
            ('static/**', 'ignore', None)]},

Hope this helps.

UPDATED Jan 14th, 00:56: Added support for in-view translation.

blog comments powered by Disqus