I think it's a time to go for implementation of i18n, so first things
first. Let's define i18n interface and behavior:

This is RFC :)

When discussion is done, update http://code.djangoproject.com/wiki/ InterNationalization with information gathered from here.

Files:
======

* i18n module is located inside django.utils.locale

* i18n will be using translations found in system locale paths

* django translations are located in
  django/share/locale/<lang>/LC_MESSAGES/django.mo

* site wide translations are located in <site_root>/locale/<lang>.mo

* application translations are located in
  <application_root>/locale/<lang>.mo

i18n module:
============

class _NullTranslation
----------------------

Wrapper around gettext.NullTranslations and base class for all
translations. Main difference from gettext.NullTranslations is added
method for getting locale name and check in add_fallback to prevent
adding already existing fall-back translation (because translations
are fetched from the cache). This class implements all *gettext
methods with added functionality to ease use of positional parameter's
in message strings (see:
http://barry.warsaw.us/papers/mailman-freenix-2003/node8.html)

class _Translation
------------------

wrapper around gettext.GNUTranslations (subclass of _NullTranslation)

get_translation(languages, app_name=None)
-----------------------------------------

Get translation object for first found language in <languages> in
paths specified above. In returned translation object fall-back
translations will be set to all matching translations found in above
described directories in this order:

    1. site locale directory
    2. django locale directory
    3. system locale directory

Finally if 'en' is not specified in <languages> fall-back to 'en' will
be added (with same search paths as above with addition of application
specific locale directory if <app_name> is not None).
If all else fails, returns _NullTranslation.

set_translation(languages, app_name=None)
-----------------------------------------

Sets *global* translation via get_translation()

current_translation()
---------------------

Returns current *global* translation

*gettext functions
------------------

Alias to same functions in *global* translation object

available_locales()
-------------------

Return a list populated with all available locales installed found in
search paths described above (it will search all application
directories within site). Returned list will be composed from dicts
with following keys (see
http://www.loc.gov/standards/iso639-2/ascii_8bits.html):

    * 'bibliographic' - alpha-3 (bibliographic) code

    * 'terminologic'  - alpha-3 (terminologic) code (when given)

    * 'code'          - alpha-2 code (when given)

    * 'english'       - English name of a language

    * 'french'        - French name of a language

    * 'native'        - native name of a language. If 'native' is not
defined it will be replaced with English name of
                        a language. Not in ISO639-2.

request object:
===============

When request object is created it will try to find locale from cookie,
then from Accept-Language header and finnaly will be fall-back to
'en'. Request object will have two additional vars:

    i18n           - for holding negotiated translation object
    i18n_requested - list of requested locales

This is done calling setup_locale() from HttpRequest inside
*Request constructor because *Request classes don't call base class
(HttpRequest) constructor.

context object:
===============

When context object is created it will create following vars (if not
exist already):

    * i18n - translation object
    * locale - currently selected locale
    * avail_locales - list of all available locales

template tags:
==============

For easy extraction with xgettext one template tag is added:

{% i18n <gettext function>(...) %}
----------------------------------

This tag will run corresponding gettext function from i18n var in
current context. All context variables are accessible within it, so
you can do:

{% i18n
   ngettext('%(foo)d singular', '%(foo)d plural', foo)
%}

Usage:
======

Django core will be using top level gettext aliases to global
translation object.

Applications will create it's own translation objects or will be
using supplied translation object from request.

---
Nebojša Đorđević - nesh
Studio Quattro - Niš - SCG


Reply via email to