This guild will help you to understand internationalization and localisation support provided by KalaPy framework.
KalaPy has full support for internationalization of text in code and templates, and format localization of dates and numbers. The terms internationalization and localization are generally abbreviated as i18n and L10n respectively. Internationalization and localization is a process of adapting a computer software to different languages and regional differences. For more information on the topic, see Wikipedia.
The general workflow of the process is like this:
KalaPy provides internationalization and localization support using Babel and pytz.
The general goal of internationalization is to allow a single web application to offer it’s contents in multiple languages.
KalaPy provides a way to specify which part of the application should be translated. The developers have to mark translatable strings using several gettext functions; and only those strings will be translated.
You can specify a translation with function kalapy.i18n.gettext() which is aliased to _() for convention. The alias _() is installed as a __builtins__ so that you can directly use _() in your code without importing it in your module.
Here is an example of translating a python module:
from kalapy import web
from kalapy.web import request
@web.route('/')
def index():
return _('Hello World!')
@web.route('/hello/<msg>')
def hello(msg):
return _('Hello %(msg)s', msg=msg)
And here is an example of translating Jinja2 template:
<title>{{ gettext('Hello World!') }}</title>
<title>{{ gettext(title) }}</title>
<title>{{ _('Hello World!') }}</title>
For more information, see Jinja2 documentation.
You can specify pluralized messages with function kalapy.i18n.ngettext().
This function does a plural-forms lookup of a given string depending on the num parameter and uses plural instead of string if num represents plural in the current locale.
For example:
from kalapy.i18n import ngettext
from foo.models import Apple
@web.route('/')
def index():
apples = Apple.all().fetch(-1)
return ngettext('%(num)d Apple', '%(num)d Apples!', num=len(apples))
In this example, if number of apples represents plural in current locale, the second string will be return. For example, if num is 2 it returns '2 Apples!' but if num is either 0 or 1, it returns '1 Apple'.
Translating templates is a real pain, especially when the strings contains some dynamically generated markup. For example, consider the following template:
Click <a href="{{ url_for('some.endpoint') }}">here</a> for more information.
As the embedded url markup is dynamically generated, it is hard to translate the entire sentence. Also, translating the sentence into pieces might result in wrong translation in some languages. However, KalaPy provides special gettext and ngettext functions for templates to solve this:
{% macro here_link(val) %}
<a href="{{ url_for('some.endpoint') }}">{{ val }}</a>
{% endmacro %}
{{ _('Click :here_link:`here` for more information.', here_link=here_link)|safe }}
You can see, rst like construct has been embedded into the string. Now, the translator can correctly translate the sentence without loosing the context.
The gettext function _() will then apply the macro to the translated string resulting correct translation.
TODO
TODO
Localization of an application is a process of adapting regional deferences. This can be achieved by creating region specific language files and formatting numbers and dates accordingly.
Once the strings in the application are marked to be translatable, next step is to create message catalogs for a particular language. A message catalog is a plain text file with extension .po, representing a single language, containing all the translatable strings and how they should be represented in particular language.
KalaPy uses Babel command line interface to generate message files. The files when translated should be compiled in .mo format in order to use the new translations.
This can be done with the admin.py script. Type following command on your terminal to see help on catalog related commands:
$ ./admin.py babel -h
Usage: admin.py babel <action> [options] [package [package [...]]]
Perform i18n message catalog related actions.
options:
-l --locale locale (e.g. en_US, fr_FR)
-d --domain message catalog domain
-v --verbose enable verbose output
-h --help display help and exit
available actions:
compile Compile message catalogs to MO files.
extract Extract messages from source files and generate a POT file.
init Create new message catalogs from generated POT file.
update Update existing message catalogs from the generated POT file.
This actions provided by admin.py babel command is identical to the pybabel script that comes with Babel.
The first step is to extract translatable strings into a message catalog template file. This can be done with admin.py babel extract command:
$ ./admin.py babel extract
This command will generate catalog templates for all the available packages in current project. If you want to extract strings for only a particular package, do this:
$ ./admin.py babel extract foo bar
Where, foo and bar are packages of current project. A locale/messages.pot file will be created under every specified packages.
The next step is to create message catalogs for a new file. If you already have created message catalog for the language, head over to next section on how to update existing catalogs. Creating new catalogs is as easy as:
$ ./admin.py babel init -l fr_FR foo
Where, foo is a package of current project, if omitted, catalogs will be created for all the available packages.
A catalog file locale/fr_FR/LC_MESSAGES/messages.po will be created under all the specified packages.
Note
Catalogs will be only created if it doesn’t exit.
If message catalog is already created and you have changed your code and think that the translatable strings have been changed, you should consider updating existing catalogs. This can be done like this:
$ ./admin.py babel update -l fr_FR foo
If you omit package name, it will perform update on all the available packages. Even if you omit the locale option it will perform update for all the existing languages for a package.
Once you have created/updated message catalog for a particular language. You have to translate the catalogs and then compile it to .mo format so that the translations can be used by the system. This can be done like this:
$ ./admin.py babel compile -l fr_FR foo
If you omit package name, it will compile catalogs of the given language for all the available packages. Even if you omit the locale option it will compile all the available catalogs.
Message catalogs for JavaScript falls under javascript domain. Perform all the above actions with option -d javascript to create message catalogs for javascript.
KalaPy provides several functions to format numbers, decimals and date values to locale specific formats. It also provides few functions to parse localized numbers, decimal and date values.
See Internationalization and Localization for more information.