Does anyone have feedback about i18n with BFG? I have a working
solution (see below) but wonder if it could not be improved. If someone
has any suggestion, I am willing to turn this (very crude) step-by-step
guide to a proper and more detailed tutorial within the BFG docs if it
may be useful.

Obviously, only steps 3 and from 8 onwards are interesting.

--- start ---
1. Install "zope.i18n":

    easy_install -i http://dist.repoze.org/bfg/current/simple zope.i18n

2. Make sure you have the latest version of zope.component (should be
   greater or equal to 3.8.0 to avoid unnecessary dependencies).

3. Add the attached "i18n.py" file in your package.

4. Add i18n markers in your template, e.g. (supposing this is a ZPT):

    <h1 i18n:domain="myapp" i18n:translate="">Welcome!</h1>

5. Create the following directory hierarchy in your package (supposing
you want a translation in French):


6. In each ".../LC_MESSAGES", add a translation file, say "myapp.po". It
uses the "gettext" standard. (Looking at an <a href=existing file is usually
the best way to get started:
this message id:

    msgid "Welcome!"
    msgstr "Bienvenue !"

  Be sure to indicate the same domain in this file and in the template
(cf. "i18n:domain" tag).

7. Compile this file with msgfmt:

    msgfmt -o "myapp.mo" -v "myapp.po"

8. In your "configure.zcml", add the following directive. It will
register "*.po" files on startup.

    <include package="zope.i18n" file="meta.zcml" />

9. In "run.app()" function, add this after the loading of the ZCML file.

    from zope.component import queryUtility
    from zope.i18n.interfaces import ITranslationDomain
    from myapp.i18n import AVAILABLE_LANGUAGES

    util = queryUtility(ITranslationDomain, name='myapp')
    for lang in util._catalogs.keys():

10. In your views, instead of calling
"repoze.bfg.chameleon_zpt.render_template_to_response()", call this method:

    from repoze.bfg.chameleon_zpt import render_template_to_response as
    from myapp.i18n import getPreferredLanguage

    def render_template_to_response(template, request, **kwargs):
        return base_render(template, **kwargs)

11. Run your application, test it and rant about me having forgotten
--- end ---

Damien Baty
AVAILABLE_LANGUAGES = set([DEFAULT_LANGUAGE]) ## will be set by 'run.app()'

def getPreferredLanguage(request, available_languages=None):
    """Return the user's preferred language (among those that are
    available in this application).

    ``available_languages`` is for test usage only.
    if available_languages is None:
        available_languages = AVAILABLE_LANGUAGES
    ## FIXME (future): add the possibility to switch language (and
    ## store value in a cookie)
    accepts = request.headers.get('Accept-Language', None)
    if not accepts:
        return DEFAULT_LANGUAGE
    ## The following may not be absolutely bullet-proof, but that
    ## should be enough. (Otherwise, we may use 'parse_accept()' from
    ## 'webob.acceptparse'.)
    for part in accepts.split(','):
        lang = part.split(';')[0].strip()
        if lang in available_languages:
            return lang
        lang = lang.split('-')[0]
        if lang in available_languages:
            return lang
Repoze-dev mailing list

Reply via email to