= [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) }}} 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 @@ geddit?
+
+ + +
+ ${select('*|text()')}