Ajax 的试验中,你会看到有一些是用英文写的。下面就让我们学习如何将应用改为支持 i18n 处理的吧。在本讲中我会讲述我实现的过程,同时对一些问题进行讨论。

django 中 i18n 的实现过程

a. 在程序和模板中定义翻译字符串。在程序中就是使用 _() 将要翻译的字符串包括起来。这里有几种做法,一种是什么都不导入,这样就使用缺省的方式,另一种是导入 django 提供的翻译函数。特别是 django 提供了 Lazy 翻译函数,特别可以用在动态语言的切换。在模板中分几种情况:

可以使用 {% trans %} 标签。它用来翻译一句话,但不能在它中间使用模板变量。如果是大段的文本,或要处理模板变量,可以使用 {% blocktrans %}{% endblocktrans %}来处理。

django 来支持简单的 Javascript 的 i18n 的处理,但有兴趣自已去看吧。

b. 定义好翻译串之后使用 bin/make-messages.py 来生成 po 文件。

django 支持多层次的处理。比如在整个 django 的源码项目,在某一个工程,在某一个应用。在不同层次去实现 i18n 时,需要在不同的层次的根目录去执行 bin/make-messages.py 。那么可以将 make-messages.py 拷贝到相应的目录去执行,特别是在你的工程或应用中。在执行make-messasges.py时,需要你预先创建conf/locale或locale目录,而make-messasges.py是不会自动为你创建的。那么 conf/locale多用在源码中,象 django 的源码就是放在 conf/locale中的。但在运行时,对于自已的项目和应用却是从 locale 中来找的。因此还是建议你创建 locale 来存放po文件。

第一次执行时:

make-messasges.py -l zh_CN

这时会生成 locale/zh_CN/LC_MESSAGES/django.po 和 django.pot 文件。

那么此时 django.po 文件只有一个头。而真正的内容在 django.pot 中呢。你可以使用 poEdit 来编辑它。

用 poEdit 打开 django.po 后,选择类目->从POT文件更新(我使用的是poEdit中文版)。这样内容就更新到po中去了。然后你就可以开始翻译了。翻译完成之后,首先要执行类目->设置,将缺省的参数修改一下。主要是:项目名称及版本,团队,团队专用电子邮件,字符集(一般为utf-8)。这些如果不改,poEdit 在保存时会报错。使用 poEdit 的一个好处是,在保存时它会自动将 po 编译成 mo 文件。

以后再更新时:

make-messasges.py -a

如果已经有多个语言文件,那么执行时会同时更新。

c. 配置

django 有一系列的策略来实现 i18n 的功能。基本上分为静态和动态。

静态是指在 settings.py 中设置 LANGUAGE_CODE 为你想要的语言。那么这里要注意,中文的语言编码是 zh-cn,但locale目录下却是 zh_CN 。这是为什么:其实一个是language(zh-cn),一个是locale(zh_CN),在 django 的 utils.translation 中有专门的方法可以进行转换。因此在 django 的程序中使用的是lanauge的形式,在目录中却是使用 locale 的形式。一旦设为静态,则它表示是全局性质的,在所有其它的策略失效后将使用这种策略。

而动态是指在运行中对于不同的用户,不同的浏览器的支持的语言可以有不同的语言翻译文件被使用。这种方式需要在settings.py中安装’django.middleware.locale.LocaleMiddleware’到MIDDLEWARE_CLASSES中去。同时如果你想在实现应用中的翻译文件被使用,也要采用这种方式。

在一个请求发送到 django 之后,如果安装了 LocaleMiddleware,它会采用下面的策略:

  • 在当前用户的session中查找 django_language 键字。
  • 如果没有找到则在cookie中查找叫 django_language 的值。
  • 如果没有找到,则查看 Accept-Language HTTP 头。这个头是由浏览器发送给服务器的。
  • 如果没有找到,则使用全局的 LANGUAGE_CODE 设置。

如果你使用 FireFox 可以在Tools->Options->Advanced->Eidt Languages设置你所接受的语言,并且将 zh-cn 放在最前面。

上面讲述得还是有些粗,建议你好好阅读 i18n 的文档。

下面开始我们的试验。

1. 修改 apps/ajax/views.py

#coding=utf-8
# Create your views here.
from django.utils.httpwrappers import HttpResponse
from django.core.extensions import render_to_response

def input(request):
    input = request.REQUEST["input"]
    return HttpResponse(_(‘<p>You input is "%(input)s"</p>’) % {’input’:input})

def json(request):
    a = {’head’:(unicode(_(‘Name’), ‘utf-8′), unicode(_(‘Telphone’), ‘utf-8′)), ‘body’:[(u'张三', '1111'), (u'李四', '2222')]}
    import simplejson
    return HttpResponse(simplejson.dumps(a))

这里对所有英文都使用 _() 进行了封装。但对于 json 方法,这里我使用 unicode(_(‘Name’), ‘utf-8′) 进行了转换。当然也许不需要这样,目前我还没有别的办法。原因是,我发现_()返回的不象我以前认为的是unicode,而是utf-8编码。那么关于它有可能是在 django.conf.global_settings.py 中有一个 DEFAULT_CHARSET 的值。缺省情况下它是 utf-8 。但现在的问题是 simplejson 需要unicode来正确处理汉字。那么我只有将 _() 返回的值转化为 unicode 。

2. 修改 settings.py

MIDDLEWARE_CLASSES = (
    "django.middleware.sessions.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.doc.XViewMiddleware",
)

这里在文档中对于 LocaleMiddleware 的顺序有要求,要求在 SessionMiddleware 之后,但在其它的 Middleware 之前。

3. 创建 apps/ajax/locale 目录

4. 拷贝 make-messasges.py 到 apps/ajax 下

5. 执行 make-messasges.py

cd apps/ajax
make-message.py -l zh_CN

6. 使用 poEdit 翻译 django.po 文件

按上面说的先更新 pot 文件,然后修改缺省的参数,再保存。

这里我没有演示模板的处理。因为 ajax 所用到的模板没有放在 ajax 目录下,而是放在 templates 目录下。因此,如果想支持 i18n 的话,目录的布置是一个问题。

7. 启动 server 测试

是不是都是中文了呢?如果不是,看一看是否浏览器没有设置成接受zh-cn。

注意,为了发贴所有半角大括号都改成了全角大括号,因此如果想运行的话,要进行替换处理。


评论

该日志第一篇评论

发表评论

评论也有版权!

click to change验证码