# i18n - Translations made easy

This package tries to simplify the workflow and development of internationalized applications. It is a thin wrapper around existing tools, in particular gettext and babel.

## Basic usage

# demo.py
#
from i18n.translator import Translator
supported_languages = ['it_IT', 'fr_FR', 'de_DE']
# activate italian translations
tr = Translator('/path/to/root', supported_languages, 'it_IT')
print tr._('Hello world!')


where /path/to/root/ is the root directory of your project. When instantiated, the Translator class automatically creates a directory called /path/to/root/languages where the translations are stored.

## Extracting messages

Before doing the actual translation, you need to extract the messages from your source files, by invoking the extract command on the i18n module, which is a wrapper around pybabel extract and pybabel update:



## Storing translations in a database

For some applications it is useful to let the user to define new translations and/or override the default ones. i18n supports this use case with the DBTranslator class, which is a subclass of Translator. When translating, DBTranslator first looks in the database: if the message is not found, it delegates to the standard gettext behavior.

DBTranslator is based on sqlalchemy. Its constructor takes an additional engine parameter:

from i18n.dbtranslator import DBTranslator
from sqlalchemy import create_engine

engine = create_engine('sqlite:///db.sqlite')
ROOT = '/path/to/root'
LANGUAGES = ['it_IT', 'fr_FR']
DEST_LANGUAGE = 'it_IT'
tr = DBTranslator(ROOT, LANGUAGES, DEST_LANGUAGE, engine=engine)
print tr._("hello world")


DBTranslator automatically creates the table translation_entries in the DB. Then, it is up to the application to provide an user interface to manipulate the table. For testing, you can use the add_translation() method to insert a new translation in the DB:

tr.add_translation("it_IT", "hello world", "ciao mondo")
print tr._("hello world") # prints "ciao mondo"


## How to use a global Translator

By design, i18n tries to completely avoid any global state. This means that you can instantiate as many Translator and DBTranslator as you want, each one referring to a different directory and/or database. This is especially useful for testing.

However, in practice most projects want to use a global translator which knows about the messages of all the components in the project. The demo application shows a way to do it in the translate.py module:

import py
from i18n.translator import Translator

# set the root of the project to the directory containing this file
ROOT = py.path.local(__file__).dirpath()
LANGUAGES = ['it_IT', 'fr_FR', 'de_DE']

tr = Translator(ROOT, LANGUAGES, 'it_IT')
_ = tr._
ngettext = tr.ngettext

if __name__ == '__main__':
tr.cmdline(sys.argv)


This way, the rest of the application can simply import and use _() and ngettext() from translate.py. Or, at your preference, import directly the tr object and use tr._() and tr.ngettext() to translate messages.

The last two lines of the code enables a convenient way to call extract and compile from the command line without having to manually specify the root dir and the supported languages. Just run:

\$ python translate.py extract     # ...or compile
`

## Acknowledgments

The development of this package has been generously funded by S3 s.r.l..