    .. -*- coding: utf-8 -*-

    Internationalization (I18N)
    ===========================

    Page 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.

    API
    ---

    To demonstrate the high-level API, the following template requires
    translation of tag contents.

      >>> from chameleon.zpt.template import PageTemplate
      >>> template = PageTemplate("""\
      ...
... Default ...
""") Without passing a language, we simply get the default value. >>> print template.render()
Default
    To translate messages, we define a translation function. The following
    describes the method signature:

      >>> def translate(msgid, domain=None, mapping=None, context=None,
      ...               target_language=None, default=None):
      ...     return msgid.upper()

    Let's initialize a new template instance, this time passing in a
    translation function.

      >>> template_with_translation = PageTemplate(template.body, translate=translate)

    If we now render the template, our translation message id should be
    uppercased.

      >>> print template_with_translation.render()
MSGID
    When ``zope.i18n`` is available (separately available from the Python
    Package Index), this framework is used for translation. We will use
    this for the remainder of this test.

    The following sets up a translation domain that provides mock
    translations for the German language code, ``"de"``.

      >>> from zope import interface
      >>> from chameleon.core import utils

      >>> from zope.i18n.interfaces import ITranslationDomain
      >>> class MockTranslationDomain(object):
      ...     interface.implements(ITranslationDomain)
      ...
      ...     def translate(self, msgid, mapping=None, context=None,
      ...                   target_language=None, default=None):
      ...         if target_language != 'de':
      ...             return default
      ...
      ...         mock ="Mock translation of '%s'" % \
      ...             utils.htmlescape(msgid)
      ...         if mapping:
      ...             mock += ' mapping=%s' % mapping
      ...         return mock + '.'

      >>> from zope import component
      >>> component.provideUtility(MockTranslationDomain(), ITranslationDomain, name="test")

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

    Now we'll render the template again---passing German as the language.

      >>> print template.render(target_language='de')
Mock translation of 'msgid'.
Let's try infering the translation message id from the tag body. >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = PageTemplate(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. ...

...

... 18 bananas. ...

...
    """

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

18 bananas.

18 bananas.

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

Mock translation of '${count} bananas.' mapping={'count': u'18'}.

18 bananas.

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

    Without a language this gives:

      >>> template = PageTemplate(body)
      >>> print template.render()
I want 12 bananas and 8 apples.
In German: >>> print template.render(target_language='de')
Mock translation of 'I want ${bananas} bananas and ${apples} apples.' mapping={'bananas': u'12', 'apples': u'8'}.
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_nov', domain="test", default=u"November")

    Without passing a language.

      >>> template = PageTemplate(body)
      >>> print template.render(year=year, monthname=monthname)
November 2008
Passing German: >>> print template.render(year=year, monthname=monthname, target_language='de')
Mock translation of 'month_nov'. 2008
Entities and dynamic translation strings: >>> body = """\ ...
... ... ® > ... < ... ...
    """

      >>> template = PageTemplate(body)
      >>> print template.render()
® > <
Translating entities: >>> template = PageTemplate("""\ ...
... ... ® ... < ... ...
""") >>> print template.render()
® <
>>> print template.render(year=year, monthname=monthname, target_language='de')
Mock translation of '® <'.
If we're replacing or inserting content dynamically, and this evaluates to ``None``, omit the tag even if we're translating. >>> body = """\ ...
... ... Will appear as an empty tag. ... ... ... Won't appear. ... ...
    """

      >>> template = PageTemplate(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 = PageTemplate(body)
      >>> print template.render()
The book is on the desk.
Dynamic content and sub-tags in a translation: >>> body = """\ ...
... ... The book is on the table. ... ...
    """

      >>> template = PageTemplate(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 = PageTemplate(body)
      >>> print template.render()
The book is on the table
>>> print template.render(target_language='de')
Mock translation of 'msg_id'.
Nested translation. >>> template = PageTemplate("""\ ...
...

#### ... ... (1 van ) ... ...

...
""") >>> print template.render(weight=32)

#### (1 van 32)

Using METAL and i18n together: >>> template = PageTemplate("""\ ...
...
...

... 18 bananas. ...

...
...
...
""") >>> print template.render()

18 bananas.

42 bananas.

Translation of tag attributes ----------------------------- A simple example to start with. >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = PageTemplate(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 = PageTemplate(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 = PageTemplate(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 = PageTemplate(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 = PageTemplate(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 PageTemplate(body).render()
Default
    Messages that contain the formatting character '%' (edge-case):

      >>> body = """\
      ...
... % ... default ...
    """

      >>> template = PageTemplate(body)
      >>> print template.render()
% default
>>> print template.render(target_language='de')
Mock translation of '%'. Mock translation of '%'.
Translation of non-ASCII tag attributes --------------------------------------- A simple example to start with. >>> body = """\ ...
... ... Default ... ...
    """

    Not passing a language:

      >>> template = PageTemplate(body)
      >>> print template.render()
Default
Passing German: >>> print template.render(target_language='de')
Default