• 翻译与JavaScript
    • javascript_catalog视图
    • 使用JavaScript翻译目录
    • 创建JavaScript翻译目录

    翻译与JavaScript

    将翻译添加到JavaScript会引起一些问题:

    • JavaScript代码无法访问一个 gettext 的实现。

    • JavaScript 代码并不访问 .po或 .mo 文件;它们需要由服务器分发。

    • 针对JavaScript的翻译目录应尽量小。

    Django已经提供了一个集成解决方案: 它会将翻译传递给JavaScript,因此就可以在JavaScript中调用 gettext 之类的代码。

    javascript_catalog视图

    这些问题的主要解决方案就是 javascript_catalog 视图。该视图生成一个JavaScript代码库,包括模仿 gettext 接口的函数,和翻译字符串的数组。 这些翻译字符串来自于你在info_dict或URl中指定的应用,工程或Django内核。

    像这样使用:

    1. js_info_dict = {
    2. 'packages': ('your.app.package',),
    3. }
    4. urlpatterns = patterns('',
    5. (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
    6. )

    packages 里的每个字符串应该是Python中的点分割的包的表达式形式(和在 INSTALLED_APPS 中的字符串相同的格式),而且应指向包含 locale 目录的包。 如果指定了多个包,所有的目录会合并成一个目录。 如果有用到来自不同应用程序的字符串的JavaScript,这种机制会很有帮助。

    你可以动态使用视图,将包放在urlpatterns里:

    1. urlpatterns = patterns('',
    2. (r'^jsi18n/(?P<packages>\S+)/$', 'django.views.i18n.javascript_catalog'),
    3. )

    这样的话,就可以在URL中指定由加号( + )分隔包名的包了。 如果页面使用来自不同应用程序的代码,且经常改变,还不想将其放在一个大的目录文件中,对于这些情况,显然这是很有用的。 出于安全考虑,这些值只能是 django.confINSTALLED_APPS 设置中的包。

    使用JavaScript翻译目录

    要使用这个目录,只要这样引入动态生成的脚本:

    1. <script type="text/javascript" src="/path/to/jsi18n/"></script>

    这就是管理页面如何从服务器获取翻译目录。 当目录加载后,JavaScript代码就能通过标准的 gettext 接口进行访问:

    1. document.write(gettext('this is to be translated'));

    也有一个ngettext接口:

    1. var object_cnt = 1 // or 0, or 2, or 3, ...
    2. s = ngettext('literal for the singular case',
    3. 'literal for the plural case', object_cnt);

    甚至有一个字符串插入函数:

    1. function interpolate(fmt, obj, named);

    插入句法是从Python借用的,所以interpolate 函数对位置和命名插入均提供支持:

    位置插入 obj包括一个JavaScript数组对象,元素值在它们对应于fmt的占位符中以它们出现的相同次序顺序插值 。 例如:
    1. fmts = ngettext('There is %s object. Remaining: %s',
    2. 'There are %s objects. Remaining: %s', 11);
    3. s = interpolate(fmts, [11, 20]);
    4. // s is 'There are 11 objects. Remaining: 20'
    命名插入 通过传送为真(TRUE)的布尔参数name来选择这个模式。 obj包括一个 JavaScript 对象或相关数组。 例如:
    1. d = {
    2. count: 10
    3. total: 50
    4. };
    5. fmts = ngettext('Total: %(total)s, there is %(count)s object',
    6. 'there are %(count)s of a total of %(total)s objects', d.count);
    7. s = interpolate(fmts, d, true);

    但是,你不应重复编写字符串插值: 这还是JavaScript,所以这段代码不得不重复做正则表达式置换。 它不会和Python中的字符串插补一样快,因此只有真正需要的时候再使用它(例如,利用 ngettext 生成合适的复数形式)。

    创建JavaScript翻译目录

    你可以创建和更改翻译目录,就像其他

    Django翻译目录一样,使用django-admin.py makemessages 工具。 唯一的差别是需要提供一个 -d djangojs 的参数,就像这样:

    1. django-admin.py makemessages -d djangojs -l de

    这样来创建或更新JavaScript的德语翻译目录。 和普通的Django翻译目录一样,更新了翻译目录后,运行 compile-messages.py 即可。