GNU gettext tools are great for creating i18n (web) applications. In this post,
assume that PO and MO files are ready and we will use the PO and MO files to
let Python applications speak local languages. 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] first. If you want to know how to render HTML by
Jinja2 template engine with the translated texts in PO and MO files in your
Python web application, please refer to [9].
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