    Internationalization
    --------------------

    Genshi templates support the i18n attribute language. The
    implementation is based on this document:

      * http://wiki.zope.org/zope3/ZPTInternationalizationSupport

    With the exception of i18n:data and i18n:source, the implementation is
    complete.

    To get set started, let's provide German mock translations for all
    msgids:

      >>> from zope import component
      >>> from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
      >>> td = SimpleTranslationDomain("test", {
      ...     ("de", "test_msgid") : u"Mock translation of 'test_msgid'.",
      ...     ("de", "msg_id")      : u"Mock translation of 'msg_id'.",
      ...     ("de", "tid")        : u"Mock translation of 'tid'.",
      ...     ("de", "aid")        : u"Mock translation of 'aid'.",
      ...     ("de", "Default")    : u"Mock translation of 'Default'.",
      ...     ("de", "bananas")    : u"Mock translation of ${count} bananas.",
      ...     ("de", "two_bananas"): u"Ich will ${bananas} Bananen und ${apples} Äpfels.",
      ...     ("de", "month_may")  : u"Mai",
      ...     ("de", "® <") : u"German ® <",
      ...     ("de", "The Dutch")  : u"Die Hollander",
      ...     ("de", "missing_id") : u"missing_id",
      ...     })
      >>> component.provideUtility(td, name="test")

    Translation of tag contents
    ---------------------------

    First, a simple example:

      >>> body = """\
      ...
... ... Default ... ...
""" First we need to turn the template into a callable: >>> from chameleon.genshi.template import GenshiTemplate >>> template = GenshiTemplate(body) Let's try rendering this template without passing a target language. >>> print template.render()
Default
Now we'll render the template again---passing German as the language. >>> print template.render(target_language='de')
Mock translation of 'test_msgid'.
Let's try infering the translation message id from the tag body. >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = GenshiTemplate(body)
      >>> print template.render()
Default
Passing German: >>> print template.render(target_language='de')
Mock translation of 'Default'.
We could also add a named block inside the tag. >>> body = """\ ...
...

... 18 bananas. ...

...
    """

      >>> template = GenshiTemplate(body)
      >>> print template.render()

18 bananas.

>>> print template.render(target_language='de')

Mock translation of 18 bananas.

Or two: >>> body = """\ ...
... ... I want 12 bananas and ... 8 apples. ... ...
    """

    Without a language this gives:

      >>> template = GenshiTemplate(body)
      >>> print template.render()
I want 12 bananas and 8 apples.
In German: >>> print template.render(target_language='de')
Ich will 12 Bananen und 8 Äpfels.
Here's an example from a template for a calendar widget: >>> body = """\ ...
...
... monthname ... year ...
...
    """

    We'll set up the tests such that pass in an i18n message for the month
    name.

      >>> from zope.i18nmessageid import Message

      >>> year = 2008
      >>> monthname = Message(u'month_may', domain="test", default=u"May")

    Without passing a language.

      >>> template = GenshiTemplate(body)
      >>> print template.render(year=year, monthname=monthname)
May 2008
Passing German: >>> print template.render(year=year, monthname=monthname, target_language='de')
Mai 2008
Entities and dynamic translation strings: >>> body = """\ ...
... ... ® > ... < ... ...
    """

      >>> template = GenshiTemplate(body)
      >>> print template.render()
® > <
Translating entities: >>> template = GenshiTemplate("""\ ...
... ... ® ... < ... ...
""") >>> print template.render()
® <
>>> print template.render(year=year, monthname=monthname, target_language='de')
German ® <
If we're replacing or inserting content dynamically, and this evaluates to ``None``, the translated content will be the empty string. >>> body = """\ ...
... ... Will be appear as empty string. ... ... ... Will be appear as empty string. ... ...
    """

      >>> template = GenshiTemplate(body)
      >>> print template.render()
If we have dynamic content in a translation, and it doesn't match a specific message id, it is left untouched: >>> body = """\ ...
... ... The book is on the table. ... ...
    """

      >>> template = GenshiTemplate(body)
      >>> print template.render()
The book is on the desk.
If a message id is supplied, unnamed blocks are rendered as-is. >>> body = """\ ...
... ... The book is on the table. ... ...
    """

      >>> template = GenshiTemplate(body)
      >>> print template.render()
The book is on the table
>>> print template.render(target_language='de')
Mock translation of 'msg_id'.
Translation of tag attributes ----------------------------- A simple example to start with. >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = GenshiTemplate(body)
      >>> print template.render()
Default
Passing German: >>> print template.render(target_language='de')
Default
Use an explicit msgid: >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = GenshiTemplate(body)
      >>> print template.render()
Default
Passing German: >>> print template.render(target_language='de')
Default
Use an explicit msgid with a trailing semicolon. >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = GenshiTemplate(body)
      >>> print template.render()
Default
Passing German: >>> print template.render(target_language='de')
Default
Use multiple attributes on the same tag. >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = GenshiTemplate(body)
      >>> print template.render()
Default
Passing German: >>> print template.render(target_language='de')
Default
Translation of tag content and tag attributes --------------------------------------------- A simple example to start with. >>> body = """\ ...
... ... Default, "default", 'default' ... ... ... Default, "default", 'default' ... ... ... ${'tid'} ... ... ... t${'i'}${'d'} ... ...
    """

    Not passing a language:

      >>> template = GenshiTemplate(body)
      >>> print template.render()
Default, "default", 'default' tid tid tid
Passing German: >>> print template.render(target_language='de')
Mock translation of 'tid'. Mock translation of 'tid'. Mock translation of 'tid'. Mock translation of 'tid'.
Make sure translations play nice with loops. >>> body = """\ ...
...
... Default ...
...
    """

    Not passing a language:

      >>> print GenshiTemplate(body).render()
Default
Message interpolation --------------------- Messages without a default translation just output the message string (identifier). >>> who = Message(u"The Dutch", domain="test") >>> body = """\ ...
... ${who} ...
    """

    Not passing a language:

      >>> template = GenshiTemplate(body)
      >>> print template.render(who=who)
The Dutch
Passing German: >>> print template.render(who=who, target_language='de')
Die Hollander
Using ``py:content``: >>> template = GenshiTemplate("""\ ...
... ...
    """)

    Not passing a language:

      >>> print template(who=who)
The Dutch
Passing German: >>> print template(who=who, target_language='de')
Die Hollander
    Messages from another translation domain
    ----------------------------------------

      >>> who = Message(u"The Dutch", domain="test")
      >>> body = """\
      ...
... ${who} ...
    """

    Translating:

      >>> template = GenshiTemplate(body)
      >>> print template.render(who=who, target_language='de')
Die Hollander
Messages without a translation ------------------------------ For valid msgids that have no translation GNU gettext returns the message id, which trips the zope.i18n default handling. Unfortuantely this is very common: for a newly created po files without any translations this holds for every message. zope.tal seems to get around this by doing its own PO handling. >>> body = """\ ...
... Default value ...
    """

    Translating:

      >>> template = GenshiTemplate(body)
      >>> print template.render(target_language='de')
Default value