國際化複數形式的支持與pygettext的補丁
今天把plugs中的論壇進行了一些優化,其中想使用uliweb中早就內置的timesince.py模塊。這塊須要i18n的支持。因而使用:html
uliweb i18n -l zh_CN --uliweb前端
來運行。結果報錯。其主要緣由是timesince中使用了複數形式的i18n函數ungettext。而uliweb使用的pygettext.py不支持。python
pygettext.py 是python在tools目錄下自帶的一個模塊,能夠用它來從python源碼中抽取翻譯字符串,它支持命令行,代碼也不算很複雜。因此在uliweb 中提供了純python的命令行工具。不過uliweb爲了讓其能夠支持模板和ini文件,修改了pygettext源碼,因此和python自帶的還不 徹底同樣。許多其它的python項目是使用xgettext工具來處理。由於pygettext.py不支持複數的翻譯串,我查了一下,主要區別就是對 於複數,在po文件中是這樣的:linux
msgid "month"web
msgid_plural "months"app
msgstr[0] "月"dom
msgstr[1] ""而不帶複數的形式是這樣的:
msgid "month"ide
msgstr "月"函數
原本想自已修改的,不過仍是先google一下吧,萬一有人解決了呢。結果還真找到了。有人在python的bugs網站上提交過這樣的問題,而後有人給出了一個 補丁。從pygettext.py的源碼能夠看到,它已經不少看沒有被修改過了。因而我下載了補丁,先在python帶的版本上打補丁,而後使用代碼比較工具將我須要的修改再加進去。後來還修改了po_merge.py程序。最終把這個問題基本上算是解決了。工具
python使用gettext來實現i18n支持。具體參數信息請看gettext
module幫助。
python中對於國際化的字符串,只須要外加_()便可。
如: print(_('hello world'))
而後根據user選擇的語言,建立translation對象,而後調用install方法install_()函數
到Python’s builtins namespace。如:
2 |
en_trans = gettext.install( 'messages' , locale = 'i18n_path' , languages = [ 'default_language' ]) |
3 |
zh_trans = gettext.install( 'messages' , locale 'i18n_path' , languages = [ 'zh_CH' ]) |
4 |
print (_( 'hello world' )) |
6 |
print (_( 'hello world' )) |
而對於web服務中前端頁面的國際化支持也很是簡單,和python source文檔中同樣
在須要國際化的字符串前面添加_()便可。而後在render函數中,把當前translation對象
傳入模板便可。如Tornado render_string的實現:
01 |
def render_string( self , template_name, * * kwargs): |
02 |
# If no template_path is specified, use the path of the calling file |
07 |
current_user = self .current_user, |
09 |
_ = self .locale.translate, |
10 |
static_url = self .static_url, |
11 |
xsrf_form_html = self .xsrf_form_html, |
12 |
reverse_url = self .application.reverse_url |
16 |
return t.generate( * * args) |
好了,上面搭建好i18n所須要的環境,下面就是準備對語言字符資源了。
python 工具: pygettext msgfmt
其餘工具: msgmerge
1. 建立po文檔
在當前目錄下建立locale文件夾,下面分別建en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/目錄。
在locale下面建立名爲 demo.html的文件內容以下:
3 |
< title >${_('title')}</ title > |
6 |
< a href = '' >${_('body')}</ a > |
而後打開命令行窗口,輸入 python pygettext.py -a -v -d messages -o messages.po \*.py \*.html
完成後,在當前目錄生成 messages.po 文件。
打開message.po 會看到其中的格式內容:
01 |
# SOME DESCRIPTIVE TITLE. |
02 |
# Copyright (C) YEAR ORGANIZATION |
03 |
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. |
07 |
"Project-Id-Version: PACKAGE VERSION\\n" |
08 |
"POT-Creation-Date: %(time)s\\n" |
09 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" |
10 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" |
11 |
"Language-Team: LANGUAGE <LL@li.org>\\n" |
12 |
"MIME-Version: 1.0\\n" |
13 |
"Content-Type: text/plain; charset=CHARSET\\n" |
14 |
"Content-Transfer-Encoding: ENCODING\\n" |
15 |
"Generated-By: pygettext.py %(version)s\\n" |
說明:
#: demo.html:3
msgid "title" #待轉換的字符串
msgstr "" #轉換後的字符bytes,若是爲空,則返回原字符
關鍵信息:"Content-Type: text/plain; charset=CHARSET\n
這裏的CHARSET 指定了 msgstr的codeset。通常推薦charset設定爲utf-8.
關於msgstr保存的信息須要說明:實際上它是一個bytes,是翻譯後的字符串
調用encode結果。
而當調用_()函數時,實際上會調用translation設置的默認charset來decode(具體請參考gettext module)。
即咱們在message.po設置的charset。
2. 翻譯字符資源
將生成的messages.po的分別copy至 en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/目錄下。
分別切換至en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/ 目錄,
編輯messages.po,修改添加翻譯後的字符(注:source.encode(charset))
3. 生成mo文件
分別切換目錄至en_US/LC_MESSAGES/ 和 zh_CN/LC_MESSAGES/,
在命令行輸入: python msgfmt.py messages.po 生成mo文件。
最終生成的locale tree的目錄相似linux系統的/usr/share/locale,
locale/{lang}/LC_MESSAGES/{domain}.mo
測試:
02 |
>>> en_trans = gettext.translation( 'messages' , 'e:/python/locale' , languages = [ 'en_US' ]) |
03 |
>>> zh_trans = gettext.translation( 'messages' , 'e:/python/locale' , languages = [ 'zh_CN' ]) |
04 |
>>> en_trans.gettext( 'title' ), en_trans.gettext( 'body' ) |
06 |
>>> zh_trans.gettext( 'title' ), zh_trans.gettext( 'body' ) |
07 |
( 'HTML Head 頭' , 'HTML Body 測試' ) |
08 |
>>> en_trans.install() |
09 |
>>> _( 'title' ), _( 'body' ), _( 'hello' ) |
10 |
( 'title' , 'body' , 'hello' ) |
11 |
>>> zh_trans.install() |
12 |
>>> _( 'title' ), _( 'body' ), _( 'hello' ) |
13 |
( 'HTML Head 頭' , 'HTML Body 測試' , 'hello' ) |
上例使用的python解析器是python3.2.2 2.*版本有些method參數稍有不一樣,請注意!
你們都知道SlideShowPro Director的語言文件是以mo和po爲結尾的,po的話能夠用EmEditor打開,可是mo的話,由於是Linux系統下的文件,因此 須要反編譯成po文件才能打開,下面就是來跟你們介紹一下相關的軟件和使用方法。
1、先來介紹一下相關的軟件:
1.編譯反編譯軟 件"gettext"
下載地址
2.po 文件的編輯軟件"poedit"
下載地址 下載地址
2、 接下來來講說他們的使用方法:
1.下載好的"gettext"是一個安裝文件,默認安裝路徑是C:\Program Files\GnuWin32\,當你須要把D盤根目錄下的default.mo反編譯成default.po時,你能夠在開始菜單的 「運行」中輸入"cmd",而後ms-dos界面下輸入引號中的內容"C:\Program Files\GnuWin32\bin\msgunfmt.exe d:\default.mo -o d:\default.po"便可完成反編譯。
2.編譯的 話有兩種辦法,第一種就是仍舊使用"gettext」軟件,輸入"C:\Program Files\GnuWin32\bin\msgfmt.exe -o d:\default.mod:\default.po"便可完成編譯工做。
注:用此方法反編譯後再編譯回來的文件和源文件是徹底相同的。
第 二種就是用"poedit"軟件打開一個反編譯後的po文件,翻譯後點選「保存消息目錄文檔」,它就會自動生成相同文件名的.mo文件。
注:用此方法生成mo文件時可能會報錯,生成的文件會和原來的有差別。