免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9156 | 回复: 2
打印 上一主题 下一主题

jinja2的I18N解决方案(不使用babel/Django,无关WEB框架本身) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-08 10:03 |只看该作者 |倒序浏览
本帖最后由 cdhigh 于 2013-08-08 18:05 编辑

鄙人的KindleEar已经正常运行了一个多月了,为何一直没有实现I18N呢,说来话长,时间不充裕是其一,但是最重要的是因为jinja2的I18N官方推荐实现是要依赖babel和pytz/gaepytz,而我讨论太多的第三方库,本来就是,python都已经自带gettext库了,何必为了一点点的优点而要安装那么多第三方库。
为此,我也多次的搜索网络,一般来说jinja2的I18N实现方案有两种:
1.官方推荐的使用babel/pytz。
2.配合django的I18N模块。
两个方案我都不喜欢,但是除此之外,没有找到其他的解决方案,无奈,只好自己啃各种文档和不停试验,总算解决,原来如此简单,不知为何网络上没有出现?
写在这里也是为了让后人不要再头疼了。
(KindleEar 1.6版本实现了I18N支持)

1.
  1. import gettext
复制代码
2. jinja2创建Environment时声明使用扩展‘jinja2.ext.i18n’
  1. jjenv = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'),extensions=['jinja2.ext.i18n'])
复制代码
3. 安装翻译组件,这里写成一个函数,初始化时调用一次设置默认语言,切换语言时再调用即可,比如:set_lang('zh-cn')
  1. def set_lang(lang):
  2.        #'lang'表示语言文件名为lang.mo,'i18n'表示语言文件名放在‘i18n'目录下,比如:
  3.        #中文翻译目录和文件:i18n\zh-cn\LC_MESSAGES\lang.mo
  4.        gettext.install('lang', 'i18n', unicode=True)
  5.        tr = gettext.translation('lang', 'i18n', languages=[lang])
  6.        tr.install(True)
  7.        jjenv.install_gettext_translations(tr)
复制代码
4. 到python安装目录Tools\i18n下直接执行pygettext.py,则会生成一个messages.pot文件,打开之,把里面的CHARSET和ENCODING都修改为utf-8,另存此pot文件为utf-8格式,然后改名为lang.po。
5. 执行命令 python msgfmt.py lang.po,生成lang.mo,拷贝到i18n/en/LC_MESSAGES/,则英文支持完成了
6. 如果你的程序不复杂,则直接编辑lang.po,在后面添加msgid "“/msgstr ""对即可,一行msgid,一行msgstr,不过还是建议执行命令:python pygettext.py yourfile.py,然后生成messages.pot,翻译此文件然后改名为lang.po,再执行:
python msgfmt.py lang.po生成翻译后的lang.mo,拷贝到i18n/zh-cn/LC_MESSAGES/,中文支持完成。
7.在源py文件中使用_()函数将要翻译的字符串都括起来,比如_("English")
8.在jinja2模板中的字符串翻译可以使用两种方式:
    1> {{_("English")}}
    2>{%trans%}English{%endtrans%}

论坛徽章:
0
2 [报告]
发表于 2013-08-08 10:14 |只看该作者
本帖最后由 cdhigh 于 2013-08-08 10:31 编辑

具体应用,根据浏览器语言来更改网页语言:
1.要获取浏览器语言,查询HTTP头的HTTP_ACCEPT_LANGUAGE字段即可,根据WEB框架不同,获取方法不同,web.py代码如下,以支持两种语言为例:
  1. def browerlang(self):
  2.         lang = web.ctx.env.get('HTTP_ACCEPT_LANGUAGE', "zh-cn")
  3.         return "zh-cn" if lang.startswith("zh") else "en"
复制代码
2.除此之外,如果还需要用户不管浏览器语言种类,更改为其他语言类型,则可以通过cookie或session来实现,这是一个使用session的代码片段,在网页渲染前调用即可(用户选择的语言先要保存在session.lang,这个要你自己实现,很简单):
  1. def set_lang(self):
  2.         if session.login==1 and session.lang:
  3.             set_lang(session.lang)
  4.         else:
  5.             set_lang(self.browerlang())
复制代码

论坛徽章:
0
3 [报告]
发表于 2015-09-15 09:38 |只看该作者
hi,
   我也是按照你帖子那样做的,怎么模板无法使用 "_" 或 %trans%
   如果自己定义"_"将加入app.context_processor 才可以;为什么?

回复 1# cdhigh
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP