GNU gettext tools are great for creating i18n (web) applications. In this post,
assume that PO and MO files generated by gettext are ready. We will use the
PO and MO files to let Python (web) applications render HTML of specific
languages by Jinja2 template engine. If you do not know what PO or MO files
are, or you do not know how to create them by gettext tools, please read my
previous post [1] and [9] first.
I will show how to use MO and PO files by example. In the example, we support
two locale, zh_TW (Traditional Chinese) and vi_VN (Vietnamese). The zh_TW
PO file are located at locale/zh_TW/LC_MESSAGES/messages.po and vi_VN PO
file are located at locale/vi_VN/LC_MESSAGES/messages.po.
zh_TW PO file locale/zh_TW/LC_MESSAGES/messages.po:
# Chinese translations for PACKAGE package.# Copyright (C) 2013 THE PACKAGE'S COPYRIGHT HOLDER# This file is distributed under the same license as the PACKAGE package.# Automatically generated, 2013.#msgid""msgstr"""Project-Id-Version: PACKAGE VERSION\n""Report-Msgid-Bugs-To: \n""POT-Creation-Date: 2013-06-04 10:20+0800\n""PO-Revision-Date: 2013-03-10 05:19+0800\n""Last-Translator: Automatically generated\n""Language-Team: none\n""Language: zh_TW\n""MIME-Version: 1.0\n""Content-Type: text/plain; charset=UTF-8\n""Content-Transfer-Encoding: 8bit\n"msgid"Home"msgstr"首頁"msgid"Canon"msgstr"經典"msgid"About"msgstr"關於"msgid"Setting"msgstr"設定"msgid"Translation"msgstr"翻譯"
vi_VN PO file locale/vi_VN/LC_MESSAGES/messages.po:
#!/usr/bin/env python# -*- coding:utf-8 -*-"""References:http://docs.python.org/2/library/gettext.htmlhttp://jinja.pocoo.org/docs/extensions/http://webpy.org/cookbook/i18n_support_in_template_filehttp://webpy.org/cookbook/runtime-language-switchhttps://code.google.com/p/webapp-improved/source/browse/webapp2_extras/i18n.pyhttp://docs.python.org/2/library/threading.html"""importosimportgettextimportthreadinglocaledir=os.path.join(os.path.dirname(__file__),'locale')domain='messages'threadLocalData=threading.local()threadLocalData.locale='en_US'# find out all supported locales in locale directorylocales=[]fordirpath,dirnames,filenamesinos.walk(localedir):fordirnameindirnames:locales.append(dirname)breakAllTranslations={}forlocaleinlocales:AllTranslations[locale]=gettext.translation(domain,localedir,[locale])defgettext(message):returnAllTranslations[threadLocalData.locale].gettext(message)defugettext(message):returnAllTranslations[threadLocalData.locale].ugettext(message)defngettext(singular,plural,n):returnAllTranslations[threadLocalData.locale].ngettext(singular,plural,n)defungettext(singular,plural,n):returnAllTranslations[threadLocalData.locale].ungettext(singular,plural,n)defsetLocale(locale):iflocaleinlocales:threadLocalData.locale=localeif__name__=='__main__':# for test purposefordirpath,dirnames,filenamesinos.walk(localedir):fordirnameindirnames:print(dirname)break
The HTML to be rendered is saved as view/demo.html:
<!doctype html><html><head><title>i18n Python webapp with gettext and jinja2</title></head><body><div>{{_("Home")}}</div><div>{{_("Canon")}}</div><div>{{_("About")}}</div><div>{{_("Setting")}}</div><div>{{_("Translation")}}</div></body></html>
Use above module and template file to render HTML with translated texts: