= [wiki:GenshiTutorial Genshi Tutorial]: Adding Internationalization =
To internationalize our application we'll use [http://babel.edgewall.org Babel].
{{{
easy_install Babel
}}}
To get the basic info on how to work with message catalog using Babel [http://babel.edgewall.org/wiki/Documentation/0.9/messages.html read this], I'll just follow you through the basic procedures.
First we'll create a `locale` directory under `geddit` which will hold the message catalogs. Next, we'll create a mapping file which will tell Babel how to handle the several type of files. Create a `mappings.cfg` on the directory above the geddit one and add inside:
{{{
# Extraction from Python source files
[python: **.py]
# Extraction from Genshi HTML and text templates
[genshi: **/templates/**.html]
}}}
The above will tell Babel that `.py` files should be handled by the python extractor and that the `.html` files should be handled by the Genshi extractor.
Now let's extract some messages to be translated:
{{{
pybabel extract -o geddit/locale/geddit.pot -F ./mappings.cfg geddit
}}}
The output should be similar to:
{{{
extracting messages from geddit/__init__.py
extracting messages from geddit/controller.py
extracting messages from geddit/form.py
extracting messages from geddit/model.py
extracting messages from geddit/translator.py
extracting messages from geddit/lib/__init__.py
extracting messages from geddit/lib/ajax.py
extracting messages from geddit/lib/template.py
extracting messages from geddit/templates/_comment.html
extracting messages from geddit/templates/_form.html
extracting messages from geddit/templates/comment.html
extracting messages from geddit/templates/index.html
extracting messages from geddit/templates/info.html
extracting messages from geddit/templates/layout.html
extracting messages from geddit/templates/submit.html
writing PO template file to geddit/locale/geddit.pot
}}}
Now let's create the English catalog which normally isn't translated:
{{{
pybabel init -D geddit -i geddit/locale/geddit.pot -d geddit/locale/ -l en
}}}
And, since I'm Portuguese, we'll create a Portuguese catalog to serve as an example:
{{{
pybabel init -D geddit -i geddit/locale/geddit.pot -d geddit/locale/ -l pt_PT
}}}
On this step you can create a catalog in your mother language if not english so that you can see Geddit translated.
Edit the contents of the resulting `geddit.po` for the locale you created, translate it, save and exit.
Next step will involve compiling these catalogs so that they can be used by python's gettext module:
{{{
pybabel compile -D geddit -d geddit/locale/ -f --statistics
}}}
Now, our Geddit application needs to use and know how to use these translated catalogs.
Let's modify `geddit/controller.py` with(this is a diff):
{{{
#!diff
Index: geddit/controller.py
===================================================================
--- geddit/controller.py (revision 766)
+++ geddit/controller.py (working copy)
@@ -92,8 +92,40 @@
links = sorted(self.data.values(), key=operator.attrgetter('time'))
return template.render(links=links)
+ @cherrypy.expose
+ def set_lang(self, language):
+ import gettext
+ import formencode
+ import __builtin__
+ locale_dir = os.path.join(os.path.dirname(__file__), 'locale')
+ domain = 'geddit'
+ codeset= 'utf-8'
+
+ gettext.bindtextdomain(domain, locale_dir)
+ gettext.textdomain(domain)
+
+ try:
+ translator = gettext.translation(domain,
+ locale_dir,
+ languages=[language],
+ codeset=codeset)
+ except IOError, error:
+ language=['en']
+ translator = gettext.translation(domain,
+ locale_dir,
+ languages=language,
+ codeset=codeset)
+ formencode.api.set_stdtranslation(languages=[language])
+ __builtin__._ = translator.ugettext
+ raise cherrypy.HTTPRedirect('/')
+
+
def main(filename):
+ import __builtin__
+ from gettext import NullTranslations
+
+ __builtin__._ = NullTranslations().ugettext
# load data from the pickle file, or initialize it to an empty list
if os.path.exists(filename):
fileobj = open(filename, 'rb')
}}}
Our `geddit/lib/template.py` with(also diff):
{{{
#!diff
Index: geddit/lib/template.py
===================================================================
--- geddit/lib/template.py (revision 766)
+++ geddit/lib/template.py (working copy)
@@ -4,6 +4,7 @@
from genshi.core import Stream
from genshi.output import encode, get_serializer
from genshi.template import Context, TemplateLoader
+from genshi.filters import Translator
from geddit.lib import ajax
@@ -42,6 +43,7 @@
template = loader.load(args[0])
else:
template = cherrypy.thread_data.template
+ template.filters.insert(0, Translator(_))
ctxt = Context(url=cherrypy.url)
ctxt.push(kwargs)
return template.generate(ctxt)
}}}
'''WARNING''': there's an error in the above code, please see #238.
And finaly our `geddit/templates/layout.html` with(also diff):
{{{
#!diff
Index: geddit/templates/layout.html
===================================================================
--- geddit/templates/layout.html (revision 766)
+++ geddit/templates/layout.html (working copy)
@@ -19,6 +19,16 @@