Mako Internationalization

注釈

This recipe is extracted, with permission, from a blog post made by Alexandre Bourget.

First, add subscribers within your Pyramid project's __init__.py.

1def main(...):
2    # ...
3    config.add_subscriber('YOURPROJECT.subscribers.add_renderer_globals',
4                          'pyramid.events.BeforeRender')
5    config.add_subscriber('YOURPROJECT.subscribers.add_localizer',
6                          'pyramid.events.NewRequest')

Then add, a subscribers.py module to your project's package directory.

 1# subscribers.py
 2
 3from pyramid.i18n import get_localizer, TranslationStringFactory
 4
 5def add_renderer_globals(event):
 6    # ...
 7    request = event['request']
 8    event['_'] = request.translate
 9    event['localizer'] = request.localizer
10
11tsf = TranslationStringFactory('YOUR_GETTEXT_DOMAIN')
12
13def add_localizer(event):
14    request = event.request
15    localizer = get_localizer(request)
16    def auto_translate(*args, **kwargs):
17        return localizer.translate(tsf(*args, **kwargs))
18    request.localizer = localizer
19    request.translate = auto_translate

After this has been done, the next time you start your application, in your Mako template, you'll be able to use the simple ${_(u"Translate this string please")} without having to use get_localizer explicitly, as its functionality will be enclosed in the _ function, which will be exposed as a top-level template name. localizer will also be available for plural forms and fancy stuff.

This 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"))

For all that to work, you'll need to:

1(env)$ easy_install Babel

And you'll also need to run these commands in your project's directory:

1(env)$ python setup.py extract_messages
2(env)$ python setup.py init_catalog -l en
3(env)$ python setup.py init_catalog -l fr
4(env)$ python setup.py init_catalog -l es
5(env)$ python setup.py init_catalog -l it
6(env)$ python setup.py update_catalog
7(env)$ python setup.py compile_catalog

Repeat the init_catalog step for each of the langauges you need.

注釈

The gettext 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.

At this point you'll also need to add your local directory to your project's configuration.

def main(...):
   # ...
   config.add_translation_dirs('YOURPROJECT:locale')

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

 1setup(
 2    # ...
 3    install_requires=[
 4        # ...
 5        Babel,
 6        # ...
 7        ],
 8    message_extractors = {'yourpackage': [
 9            ('**.py', 'python', None),
10            ('templates/**.html', 'mako', None),
11            ('templates/**.mako', 'mako', None),
12            ('static/**', 'ignore', None)]},
13    # ...
14    )

In the above triples the last element, None in this snippet, may be used to pass an options dictionary to the specified extractor. For instance, you may need to set Mako input encoding using the corresponding option.

# ...
           ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
# ...