国际化复数形式的支持与pygettext的补丁
今天把plugs中的论坛进行了一些优化,其中想使用uliweb中早就内置的timesince.py模块。这块需要i18n的支持。于是使用:
uliweb i18n -l zh_CN --uliweb
来运行。结果报错。其主要原因是timesince中使用了复数形式的i18n函数ungettext。而uliweb使用的pygettext.py不支持。
pygettext.py 是python在tools目录下自带的一个模块,可以用它来从python源码中抽取翻译字符串,它支持命令行,代码也不算很复杂。所以在uliweb 中提供了纯python的命令行工具。不过uliweb为了让其可以支持模板和ini文件,修改了pygettext源码,所以和python自带的还不 完全一样。许多其它的python项目是使用xgettext工具来处理。因为pygettext.py不支持复数的翻译串,我查了一下,主要区别就是对 于复数,在po文件中是这样的:
msgid "month"
msgid_plural "months"
msgstr[0] "月"
msgstr[1] ""而不带复数的形式是这样的:
msgid "month"
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.编译反编译软 件"gettext"
下载地址
2.po 文件的编辑软件"poedit"
下载地址 下载地址
二、 接下来来说说他们的使用方法:
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文件时可能会报错,生成的文件会和原来的有差异。
来源:oschina
链接:https://my.oschina.net/u/206466/blog/82032