Package: i18n
This package tries to simplify the workflow and development of
internationalized applications. It is a thin wrapper around existing tools, in
particulargettextandbabel.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, theTranslatorclass automatically creates a directory
called/path/to/root/languageswhere the translations are stored.Extracting messagesBefore doing the actual translation, you need toextractthe messages from
your source files, by invoking theextractcommand on thei18nmodule,
which is a wrapper aroundpybabel extractandpybabel update:$ python -m i18n --root=/path/to/root --languages=it_IT,fr_FR,de_DE extractextractlooks for all the messages wrapped inside calls to_(),gettext()orngettext()and produces a file calledlanguages/template.pot. This is a standardgettext po file`which
contains all the messages found in the application.Moreover,extract()also creates amessage catalogfile for each of
the supported languages aslanguages/$CODE/LC_MESSAGES/messages.po, where$CODEis one of the languages listed insupported_languages(it_IT,
fr_FR and de_DE in the example above).The catalog files are now ready to be translated using one of the many
existing tools, for exampleQT LinguistorPoedit.  For the correct
functioning of the application, the entirelanguages/hierarchy needs to
be preserved. We suggest to track the variousmessages.pofiles in Version
Control System together with the other files belonging to the application.Updating messagesDuring the development of the application, you will surely add new messages to
be translated. Theextractcommand automatically handle this case: if it
finds existing catalog files, their content (including the existing
translations) is merged with the newly extracted messages.Compiling catalogsIt is necessary to compile the catalog files before using them with
gettext. By default, ourTranslatorobject automatically compiles all the
catalogs found inlanguages/, producing the corresponding.mofiles. The compilation is done only when the catalog file has been modified.
This means that in most cases you do not have to worry about the compilation
of the catalogs.If you prefer to have more control on this step, you can passautocompile=Falseto the constructor ofTranslatorand compile them
manually from the command line:$ python -m i18n --root=/path/to/root --languages=it_IT,fr_FR,de_DE compileStoring translations in a databaseFor some applications it is useful to let the user to define new translations
and/or override the default ones.i18nsupports this use case with theDBTranslatorclass, which is a subclass ofTranslator.  When
translating,DBTranslatorfirst looks in the database: if the message is
not found, it delegates to the standard gettext behavior.DBTranslatoris based onsqlalchemy. Its constructor takes an additionalengineparameter: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")DBTranslatorautomatically creates the tabletranslation_entriesin
the DB. Then, it is up to the application to provide an user interface to
manipulate the table.  For testing, you can use theadd_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 TranslatorBy design,i18ntries to completely avoid any global state. This means
that you can instantiate as manyTranslatorandDBTranslatoras 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 thetranslate.pymodule: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_()andngettext()fromtranslate.py. Or, at your preference, import directly
thetrobject and usetr._()andtr.ngettext()to translate
messages.The last two lines of the code enables a convenient way to callextractandcompilefrom the command line without having to manually specify the
root dir and the supported languages. Just run:$ python translate.py extract     # ...or compileAcknowledgmentsThe development of this package has been generously funded byS3 s.r.l..