内容


基于 Dojo 的本地化开发

Comments

什么是软件的本地化

软件本地化是“将一个软件产品按特定国家 / 地区或语言市场的需要进行加工,使之满足特定市场上的用户对语言和文化的特殊需求的软件生产活动。”具体说,就是根据目的地国家的市场需求,面向当地用户,对软件产品进行功能调整、信息翻译,本地特性开发,使其在功能、语言和外观上都符合该国家 / 地区的习惯。目前本地化的工作主要包括:

  • 页面文本内容显示的本地化
  • 时间 / 日期格式的本地化(国际化环境下使用 UTC),包括使用不同的日历
  • 数字的格式的本地化(小数点,分割号的位置,用作小数点和分割符的字符)
  • 货币的单位标识和数据格式的本地化
  • 特殊语言的界面显示方向 ( 从左到右或从右到左 )

除了以上这些我们目前重点关注的领域以外,本地化还包括一些其他的内容,比如,电话号码格式、姓名显示格式、地址格式、邮政编码格式等等。

什么是 Dojo

Dojo 是一个开源的基于 JavaScript 的 web 界面开发框架,它对常用对象进行了包装并提供一系列 widgets 来简化用户界面的开发。它能够使我们更容易地编写 JavaScript,更快速地制作大型的 Web 界面,在一定程度上使我们更容易开发动态的 Web 界面。其中 Dojo 的一个重要特性就是提供了良好的本地化支持机制。

Dojo 对页面文本内容显示的本地化支持

说到本地化,就不得不介绍其中最重要的一个概念 Locale,Locale 是根据计算机用户所使用的语言、所在国家或者地区以及当地的文化传统所定义的一个软件运行时的语言环境。所谓页面文本内容显示的本地化,就是对于同一个软件能够根据当前用户选择的 Locale,页面显示的语言动态地改变。比如为中国用户显示中文界面而不是默认的英文界面。下面主要介绍一下 Dojo 中是如何实现显示信息的本地化。

首先,在软件开发过程中,将所有的需要在页面上显示的文本内容抽取出来,以 Key 和 Value 的形式保存在一个 .js 资源文件中。如 ResourceMessage.js:

清单 1. en 文件夹下的 ResourceMessage.js
( { "localeSelect": "Locale:", "dateStr": "Date and time in localization format: ${0}.", "numStr": "Number in localization format: ${0}.", "currencyStr": "Currency in localization format: ${0}." } )

之后,我们为每种需要翻译的语言创建一个以该语言缩写命名的文件夹。

图 1. 文件目录结构
图 1. 文件目录结构

在 zh-cn 目录下,ResourceMessage.js 的代码如下。

清单 2. zh-cn 文件夹下的 ResourceMessage.js
( { "localeSelect": "区域:", "dateStr": "本地化的日期和时间格式:${0}。", "numStr": "本地化的数字格式:${0}。", "currencyStr": "本地化的货币格式:${0}。" } )

在 Web 页面中调用代码如下:

1. <script type="text/javascript" src="../dojo/dojo.js" djConfig="locale: '<%=userLocale%>'"></script> 2. dojo.registerModulePath("my.app", "../../my/app"); 3. dojo.requireLocalization("my.app", " strings "); 4. var strings = dojo.i18n.getLocalization("my.app", " ResourceMessage");

对于以上代码解释如下:

  • 第 1 行:设置 djConfig.locale 对象来指定具体哪个文件夹下的 ResourceMessage.js 文件。其中变量 userLocale 存放的是当前浏览器的 Locale。该代码加在 html 文件的开头。
  • 第 2 行:使用函数 dojo.registerModulePath 将以上文件路径注册为一个可用模块。
  • 第 3 行:使用函数 dojo.requireLocalization 来加载上述资源文件 ResourceMessage.js。
  • 第 4 行:使用函数 dojo.i18n.getLocalization 将该资源文件转化成对象的形式并返回。得到该对象后,就可以像普通的 JSON 对象一样对里面的字符串进行读取了。例如:ResourceMessage.ALL_PLACES。

Dojo 对时间、数字和货币本地化的支持

世界上各个国家有着不同的时间格式、数字格式和货币格式的惯例,比如我国日期格式排列顺序为“年 - 月 - 日”,而美国则是“月 - 日 - 年”,比如我国的小数点符号为“.”,而德国、匈牙利等国则使用“,”。针对特定的 Locale 正确地显示时间、数字和货币是本地化的一个重要部分。针对于时间、数字和货币本地化的支持,Dojo 提供了三个模块来供开发者调用:date, number 和 currency 。在应用 Dojo 的支持进行本地化的时候,Dojo 会从上述模块中调用 cldr 模块下的相应语言包进行本地化,极大程度上减轻了程序员的工作。

日期时间格式的本地化

Dojo 在 date 模块下面有一个 locale 包用来专门处理日期和时间的本地化。对一个 javascript 的 Date 对象的日期部分和时间部分,Dojo 都能进行本地化。

下面这段实例代码实现了对日期和时间的本地化:

1. dojo. require("dojo.date.locale"); 2. var mydate =new Date(2007,12,17,10,32,12); 3. var result=dojo.date.locale.format(mydate,{ formatLength :'long' , locale: 'zh-cn' });
  • 第 1 行:用来引入所需的 Dojo 模块,这样下面的代码便能调用 locale 包提供的公用函数方法。
  • 第 2 行:代码构造一个需要本地化的 Date 对象 ( 假定时间为 2007 年 12 月 17 日上午 10 点 32 分 12 秒 )。
  • 第 3 行:调用 Dojo 公用模块对时间日期进行本地化,参数中 formatLength 指定转化话的长度类型 , 可选值有:'short', 'medium' , 'long' 和 'full' 。locale 指定语言类型 ( 这里 zh-cn 为简体中文 )。

最后输出的结果为 "2007 年 12 月 17 日上午 10 点 32 分 12 秒 "。

另外 dojo.date.locale.format 的其他常用的可选项有:

  • Selector - 可选值:'time', 'date'。用来筛选 time 和 date。
  • datePattern,timePattern - 重置 date 和 time 的格式。
  • am,pm - 重置 am 和 pm 的字符串。

数字格式的本地化

对数字格式的本地化和上面提到的对时间日期的本地化类似,利用 Dojo 提供 number 模块就能够处理数字格式的转化。

下面这段实例代码实现了对数字格式的本地化:

1. dojo.require("dojo.number"); 2. var num_format=dojo.number.format( 12345.67,{ locale: 'fr-fr' }) ;
  • 第 1 行:引入所需的 Dojo 模块。
  • 第 2 行:调用 Dojo 公用模块进行本地化,参数 locale 指定语言类型 ( 这里 fr-fr 为法文 )。

最后输出的结果为 12 345,67 。从这个结果中我们看到,输出应用了法国的数字格式规则:即,千位分隔符使用空格,数字的小数点符号为“,”。

另外 dojo.number.format 其他常用的可选项有:

  • pattern - 重置数字的格式
  • type - 可选值:decimal, scientific, percent, currency 。
  • places - 设定小数点的位置。
  • round - 取近似值:值为 5 则就近取 .5;值为 0 就近取整;值为 -1 则不取近似值。

货币格式的本地化

对货币格式的本地化与数字格式的本地化也相似。Dojo 提供 currency 模块处理货币格式的转化。需要注意的是,输入参数货币量必须是一个数值。

下面这段实例代码实现了对货币格式的本地化:

1. dojo.require("dojo.currency"); 2. var cur_format=dojo.currency.format( 12345.67, {currency: "EUR"}) ;
  • 第 1 行 : 引入所需的 Dojo 模块。
  • 第 2 行 : 调用 Dojo 模块进行本地化,参数 currency 指定货币类型 ( 这里为欧元 )。

最后输出的结果为€12,345.67 。

另外 dojo.currency.format 其他常用的可选项有:

  • symbol - 重置货币符号。
  • pattern - 重置数字的格式。
  • places - 设定小数点的位置。

进行日期,时间和数字本地化时可能遇到的问题

下面描述了我们在实际工作中实现基于 Dojo 的日期,时间和数字的本地化碰到的两个具体问题以及其的解决办法。

由于 IE 和 Firefox 的处理机制不同,在 IE 中,用上面的方法是可以成功本地化的。但在 Firefox 下可能不一定生效(所用的 Dojo 版本为 1.0.1),需要添加一些额外代码,例如,添加如下的代码,将需要的模块包括进来(以中文为例):

dojo.requireLocalization("dojo.cldr", "number", 'fr-fr'); dojo.requireLocalization("dojo.cldr", "gregorian", 'zh-cn');

使用 Dojo 本地化的另一个需要注意之处是 ,Dojo 默认的 cldr 模块下的语言种类是不全的。如果开发者所需要的语言没能在其中,那么可以对 Dojo 目录 util/buildscripts/cldr 下的 ant script 进行定制,通过允许经过定制的脚本生成一个包含所需语言包的 Dojo 版本。

应用 Dojo 提供的 widgets 简化编程

Dojo 除了提供了以上的这些公用模块和方法来帮助程序员实现时间、日期、数字、货币的本地化外,还提供了一系列的支持本地化的输入型 Widgets,其中包括:ValidationTextBox,CurrencyTextBox,NumberTextBox,DateTextBox,TimeTextBox,这些 TextBox 本身就可以自动完成货币,数字,日期时间等的格式的本地化。以 NumberTextBox 为例说明:

NumberTextBox 是 Dojo 提供来专门处理与数字输入输出有关的 TextBox。与传统 TextBox 相比,NumberTextBox 可以对输入的字符进行校验,如果不为有效的数字类型,超过设定的数字范围则会提示报错。NumberTextBox 子对象有两个 INPUT 元素,一个供用户使用,另一个则是隐藏的专门负责与服务器端数据的交换。这样如果用户进行输入操作,NumberTextBox 允许用户输入本地化的数字,即使用户输入的是非本地化数字,当 NumberTextBox 失去焦点时,数字也会自动以本地化格式显示,但数据传给服务器时,传的仍然是标准的非本地化形式;如果 NumberTextBox 得到一个从服务器端来的数据,它会自动将该数据转化成本地形式并显示。

如下代码定义了一个 NumberTextBox 如何使用:

<input dojoType="dijit.form.NumberTextBox" constraints="{min:0,places:0}" required= "true" ></input>

可以看到,使用时跟普通 Widgets 并无差别。此处设定了一些参数:min 指定允许的最小值,places 指定小数点的位置,required 指定输入是否不能为空。

Dojo 对 BiDi 的支持

首先介绍一下 BiDi language 的概念,它的英文全称是 bi-directional language,中文称谓是双向字符集语言。这种语言主要包括希伯来语、阿拉伯语和乌尔都语等。它们的最大特点就是允许双向文—也就是说,他们的本土语言书写顺序是从右往左,而其中的英文单词或商标符号从左向右显示。所以本地化另外一个重要的方面是对 BiDi 的支持。Dojo 对 BiDi 的支持其实就是 widgets 对 BiDi 的支持。Dojo 除了保证 widgets 支持 html 节点属性 dir="rtl" 和 CSS 属性 direction: rtl 外,Dojo 还为 widgets 提供了一些 RTL 风格的 CSS,比如 tundra_rtl.css 和 dijitRtl.css 等。下面以 dijit.Tree 为例,说明如何实现 widgets 的镜像效果。

图 2. dijit.Tree
图 2. dijit.Tree

图 2 是 dijit.Tree 的正常显示效果,其主要代码如下:

清单 3. dijit.Tree 的实现
<div dojoType="dijit.Tree" id="mytree" store="continentStore" query="{type:'continent'}" labelAttr="name" label="Continents"> …… </div>
图 3. dijit.Tree RTL
图 3. dijit.Tree RTL

图 3 是 dijit.Tree 的镜像显示效果,两种实现方法的主要代码如下:

清单 4. dijit.Tree RTL 的实现
<div dir="rtl" class="dijitRtl"> <div dojoType="dijit.Tree" id="mytree" store="continentStore" query="{type:'continent'}" labelAttr="name" label="Continents"> …… </div> </div>
清单 5. dijit.Tree RTL 的另一种实现
<div style="direction: rtl" class="dijitRtl"> <div dojoType="dijit.Tree" id="mytree" store="continentStore" query="{type:'continent'}" labelAttr="name" label="Continents"> …… </div> </div>

只需要加上两个属性就能实现 dijit.Tree 的镜像,这就大大地减少了开发人员开发 CSS 的工作。而 Dojo 的其他 widgets 也提供了类似的方法实现页面的镜像。

Dojo 本地化的未来方向

虽然 Dojo 对于软件本地化开发提供了强大的支持。但是在具体的使用中,我们也发现其中也确实还有一些不如意的地方。比如 Dojo 自己本地化的翻译工作并不是非常的正确,这一点在其官方网站上也有说明,Dojo 申明其并不能保证这些翻译的资源文件是完全的正确和适当。又比如,其中一些 widget 对 BiDi 的支持还并不完善。Dojo 也鼓励大家向其提交这些方面的 bug。但是无论如何 Dojo 对于本地化的实现框架是非常完美的。我们有理由期待 Dojo 的本地化未来会更好。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development
ArticleID=285412
ArticleTitle=基于 Dojo 的本地化开发
publish-date=01312008