| ==================== |
| Internationalization |
| ==================== |
| |
| Jinja includes support for internationalized templates. Because usually the |
| application includes i18n/l10n code too there is no script to collect |
| translatable strings and no default translation interface. A simple |
| implementation wouldn't fit into every application so there are a few things |
| you have to do. |
| |
| |
| Writing A Translator |
| ==================== |
| |
| The most important thing is writing a translator and subclassing the |
| Environment so that Jinja knows about the translator. Then you have to |
| think of how to resolve the current language. You probably use Jinja in a |
| multithreaded environment where each thread (request) might want to have |
| a different language. The best way is putting the current language into |
| the context, this can work automatically if you create a helper function |
| for template rendering. But that's up to you. |
| |
| However. For many web applications this might be a way: |
| |
| .. sourcecode:: python |
| |
| from jinja import Environment |
| from myapplication import get_translator |
| |
| class ApplicationTranslator(object): |
| |
| def __init__(self, language): |
| self.language = language |
| self.translator = get_translator(language) |
| |
| def gettext(self, string): |
| return self.translator.ugettext(string) |
| |
| def ngettext(self, singular, plural, n): |
| return self.translator.ungettext(singuarl, plural, n) |
| |
| |
| class ApplicationEnvironment(Environment): |
| |
| def get_translator(self, context): |
| return ApplicationTranslator(context['LANGUAGE']) |
| |
| |
| env = ApplicationEnvironment() |
| tmpl = env.get_template('index.html') |
| tmpl.render(LANGUAGE='de_DE') |
| |
| This example assumes that you use gettext and have a gettext `Translations` |
| object which is returned by the `get_translator` function. But you don't |
| have to use gettext. The only thing Jinja requires is an object with to |
| functions/methods on it that return and accept unicode strings: |
| ``gettext(string)`` that takes a string, translates and returns it, a |
| ``ngettext(singular, plural, count)`` function that returns the correct plural |
| form for `count` items. Because some languages have no or multiple plural |
| forms this is necessary. |
| |
| |
| Translator Factory |
| ================== |
| |
| With Jinja 1.2 onwards it's possible to use a translator factory |
| instead of an enviornment subclass to create a translator for a context. |
| A translator factory is passed a context and has to return a translator. |
| Because of the way classes work you can also assign a translator class |
| that takes a context object as only argument as factory. |
| |
| Example: |
| |
| .. sourcecode:: python |
| |
| from jinja import Environment |
| from myapplication import get_translator |
| |
| def translator_factory(context): |
| return get_translator(context['LANGUAGE']) |
| |
| env = ApplicationEnvironment(translator_factory=translator_factory) |
| tmpl = env.get_template('index.html') |
| tmpl.render(LANGUAGE='de_DE') |
| |
| This example assumes that the translator returned by `get_translator` |
| already has a gettext and ngettext function that returns unicode strings. |
| |
| |
| Collecting Translations |
| ======================= |
| |
| The next step is to collect the translations. Every Jinja environment |
| provides a function called `get_translations` which collects all |
| translatable strings from an template. |
| |
| Example: |
| |
| .. sourcecode:: pycon |
| |
| >>> env.get_translations('index.html') |
| [(1, u'foo', None), (2, u'Foo', None), (3, u'%(count)s Foo', u'%(count)s Foos')] |
| |
| The first item in the tuple is the linenumer, the second one is the |
| singular form and the third is the plural form if given. |
| |
| Because Jinja is not bound to gettext you can now use these strings to |
| create translation files for any translation system. |
| |
| *New in Jinja 1.1* You can now extract translations from strings according |
| to the current envrionment settings too by using the environment method |
| `get_translations_for_string` which takes a string containing a template |
| as only argument. The return value is the same as for `get_translations`. |