i18n in Pyramid for mako template

You may find official document here , But I'll try descriping how to make i18n works with pyramid, gettext and mako template by showing you some simple codes.

  1. Starts with a localizer translator
    _ = TranslationStringFactory('myproject')
    
    def _t(request, trans):
        return request.localizer.translate(_(trans))
    
  2. Register locale directory, you should put your locale directory under myproject by default, you should see myproject/locale and myproject/myproject in the same level
    # register translator function
    config.add_request_method(_t, '_')
    # register locale search directory
    config.add_translation_dirs("myproject:locale")
    
  3. Mark your i18n language support in template or python source file
    # in python source file
    @view_config('index', renderer="myproject:templates/index.html")
    def my_view(request):
        title = _t(request, _(u"我的项目"))
        context = dict(title=title, request=request)
        return context
    
    # in mako template
    <nav id="nav">
        <a href="/about">${request._(u'About')}</a>
        <a href="/tags">${request._(u'TAGS')}</a>
    </nav>
    
  4. Extract token from python source files and mako templates
    • Install gettext in centos: yum install gettext

    • Install lingua: pip install lingua

    • Set up lingua config file: lingua.ini, put it under myproject root directory, in the same level of setup.py
      # content in lingua.ini
      [extensions]
      .html = mako
      .py = python
      
    • Extract tokens to myproject/locale/myproject.pot by pot-create  ./ -c ./lingua.ini -o ./myproject/locale/myproject.pot, you may noticed pot-create is a script from lingua

    • Update translations files myproject/locale/en/LC_MESSAGES/myproject.po by msgmerge --update -q myproject/locale/en/LC_MESSAGES/myproject.po myproject/locale/myproject.pot

    • After then, you can create you translations by a open source software poedit, but remember that you should put the translation result file to myproject/locale/en/LC_MESSAGES/myproject.mo

That's all you need to do to make i18n happen in your project.

Besides, we can create a setup command for the Extract token operation by following source code in setup.py:

class CustomCommand(distutils.cmd.Command):
    """
    Customize commands for setup scripts.
    """

    description = 'Custom commands'
    user_options = [
        # The format is (long option, short option, description).
        ('action=', 'a', 'Specify the action: [extract_i18n]'),
    ]

    def initialize_options(self):
        """Set default values for options."""
        # Each user option must be listed here with their default value.
        self.action = 'doc'

    def finalize_options(self):
        """Post-process options."""

    def run(self):
        """Run command."""
        if self.action == 'extract_i18n':
            dir_name = 'myproject/locale/zh_CN/LC_MESSAGES'
            if not os.path.exists(dir_name):
                os.makedirs(dir_name)
            dir_name = 'myproject/locale/en/LC_MESSAGES'
            if not os.path.exists(dir_name):
                os.makedirs(dir_name)
            os.system("pot-create  ./ -c ./lingua.ini -o "
                      "myproject/locale/myproject.pot")

            prefix = ''
            cmd_cn = ("%smsgmerge --update "
                      "myproject/locale/zh_CN/LC_MESSAGES/myproject.po "
                      "myproject/locale/myproject.pot") % prefix
            cmd_en = ("%smsgmerge --update -q "
                      "myproject/locale/en/LC_MESSAGES/myproject.po "
                      "myproject/locale/myproject.pot") % prefix

            self.announce(cmd_cn, distutils.log.INFO)
            os.system(cmd_cn)
            self.announce(cmd_en, distutils.log.INFO)
            os.system(cmd_en)

setup(
    ...
    cmdclass={
        'myproject': CustomCommand
      }
)

You can do Extract token by python setup.py myproject -a extract_i18n.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.