本地化 Firefox OS 应用

Firefox OS 应用正在全球范围内使用 - 包括西班牙、波兰、哥伦比亚和委内瑞拉,还有更多国家即将加入 - 所以从一开始就考虑本地化您的应用非常重要。但是,由于开放的网络本身就非常开放,因此在本地化方面有很多框架和技术可供选择。例如,Jed Gettext 风格的库是一个流行的传统选项。还有一些新的本地化平台正在开发中,这些平台扩展了当前库中可用的功能。例如,Mozilla 正在进行一个非常有前景的 本地化项目,它通过各种引人注目的新功能扩展了 L10n。要了解更多信息,请查看 Mozilla 的 工具组

在这篇文章中,我们将讨论如何使用当前用于 Firefox OS 的 Gaia 层本地化的库来本地化您的 Firefox OS 应用。Gaia 包含了操作系统中的所有内置网络应用,包括拨号器和联系人管理器,因此它提供了一个很好的模仿模型。但是,如果您决定使用这种方法,请记住,库的某些功能(例如 l10n_date.js 使用非标准的 toLocaleFormat 方法)不具有跨浏览器兼容性,并且知道 Gaia 可能会在未来某个时候迁移到 L20n。

L10n.js

目前,Firefox OS Gaia 使用了 Fabien Cazenave 的 L10n.js 库的修改版本来本地化 Firefox OS 中可用的默认应用。它在 Gaia 的 源代码树 中可用。该库依赖于基于键值对的属性格式。L10n.js 解析器还支持可以用于客户端语言选择的导入规则。默认的 Gaia 应用使用 ini 文件来指定导入语句,并使用链接标签来加载 ini 文件。

作为一个工作示例,请查看蓝牙应用,它可以用来传输文件。该应用的属性文件以以下方式结构化。
bluetooth
此应用包含四个语言环境(ar、en-US、fr 和 zh-TW)的属性文件。下面列出了部分 en-US 属性文件。

bluetooth = Bluetooth
confirmation = Confirmation
bluetooth-status-description = Bluetooth is disabled
turn-bluetooth-on = Do you want to turn Bluetooth on?
cancel = Cancel
turn-on = Turn On

如您所见,它是一个简单的键值对属性文件,包含要本地化的字符串集。所有这些文件都存储在蓝牙应用的 locales 目录中。此外,此文件夹还包含一个 locales.ini 文件,其内容如下

@import url(bluetooth.en-US.properties)

[ar]
@import url(bluetooth.ar.properties)

[fr]
@import url(bluetooth.fr.properties)

[zh-TW]
@import url(bluetooth.zh-TW.properties)

ini 文件根据应用用户的语言环境指定要加载的属性文件。它充当多语言词典,列出了所有支持的语言环境。此外,在此特定实例中,如果未找到给定用户语言环境的条目,则 en-US 属性文件将用作默认语言环境。此 ini 文件通过使用链接标签的以下语法加载。

rel 属性也可以设置为“prefetch”来预加载 ini 文件以提高性能。

L10n 元素属性

通过添加 data-l10n-id 属性来定义需要翻译的元素,该属性是在属性文件中定义的键。例如,需要本地化的标题可以这样写

Label One

属性“label1”的值用作属性文件中的键。可以使用参数替换和复数宏在属性文件中创建复杂的字符串。

参数替换

参数替换是通过将参数用双花括号 {{arg}} 包围来实现的。然后可以使用类似以下语法的语法为特定用户定制消息

loginmessage = Hello {{user}}, glad you decided to visit

可以使用 data-l10n-args 属性设置参数的默认值。此属性期望一个 JSON 格式的值。在上面的示例中,可以通过使用以下 HTML 为 user 参数设置默认值。

Label One

复数宏

复数宏可用于根据参数值定制消息。宏接受一个数字值,并返回零、一、二、少、多或其他。返回值取决于传入的值和当前语言环境的 Unicode 复数规则。例如,针对 en-US 语言环境的定制邮件消息可能如下所示

mailMessage = {[ plural(n) ]}
mailMessage[zero]  = you have no messages
mailMessage[one]   = you have one message
mailMessage[two]   = you have two messages
mailMessage[other] = you have {{n}} messages

Mail Message

L10n 脚本

大多数默认的 Firefox OS 应用使用类似以下内容的脚本标签来加载 L10n.js 库。

要在您自己的应用程序中使用此库,您需要将 l10n.js 文件复制到您的本地项目并更改 source 属性。

加载后,L10n.js 库将公开一个“navigator.mozL10n”对象,可用于客户端本地化。

下面描述了 mozL10n 最有用的方法和属性。

get 方法

get 方法用于获取当前语言环境的翻译后的字符串。该方法接受一个 key 参数和一个可选的 args 参数。key 参数指定在属性文件中定义的键。

navigator.mozL10n.get("mylabel")

args 参数可用于传递包含参数的字符串的 JSON 格式的参数。

//properties file
welcome = Welcome {{user}}!

//JavaScript
alert( navigator.mozL10n.get(“welcome”,  { user: "Martin" }));

localize 方法

localize 方法可用于将 L10n 属性添加到动态创建的内容中。该方法接受一个 element 参数、一个 id 参数和一个可选的 args 参数。element 参数指定要本地化的元素。id 参数指定要分配给元素的基于 L10n 的属性 id。可选的 args 参数允许您创建 data-l10n-args 属性并设置其 JSON 值。

var button2 = document.querySelector("#button2");
if (button2) {
    button2.onclick = function () {
        var myElement = document.createElement('span');
        var lblTxt =document.createTextNode("My Label");
        myElement.appendChild( lblTxt );
        navigator.mozL10n.localize(myElement, 'label3'{ arg: "myarg" });
        document.body.appendChild(myElement);
    }
};

这将创建以下 HTML。

 My Label

此外,文本也将立即翻译。

ready 方法

ready 方法允许您在当前文档的本地化完成后定义回调。

var button1 = document.querySelector("#button1");
if (button1) {
    button1.onclick = function () {
        navigator.mozL10n.language.code = "fr";
        navigator.mozL10n.ready( function() {
            alert(navigator.mozL10n.get("button1"));
        });
    }
};

language 属性

language 属性包含语言代码的 getter 和 setter。language 属性还包含语言方向的 getter,用于支持从右到左(阿拉伯语或希伯来语)和从左到右的语言。

var mycode = navigator.mozL10n.language.code;
navigator.mozL10n.language.code = "fr";
navigator.mozL10n.language.direction //returns rtl or ltr

L10n_Date 脚本

为了进行日期和时间操作,Gaia 应用使用 l10n_date.js 库扩展了 L10n.js 的功能。与 l10n.js 库一样,它实现了可能与所有浏览器不兼容的某些功能。该库在 Gaia 的 源代码树 中可用,并使用本文 L10n.js 部分中描述的相同属性结构。使用此库的 Gaia 应用都依赖于一组共享的属性文件和一个 date.ini 文件来导入特定于语言环境的属性文件。date.ini 文件位于 Gaia 的 源代码树 中,特定于语言环境的属性文件位于 https://github.com/mozilla-b2g/gaia/tree/master/shared/locales/date 目录中。这些属性文件定义了一周的开始日期、简短日期格式以及月份名称等格式和字符串。要在您自己的应用程序中使用此库,您需要将所有文件复制到您的特定项目。ini 文件和脚本文件以类似于 L10n.js 库的方式加载。


使用 L10n_Date 库的格式方法时,属性文件中的字符串可以使用标准的 C++ 日期/时间 格式化代码。作为一个示例,请查看 Gaia 时钟应用的属性文件。此文件包含以下针对 en-US 语言环境的 dateFormat 条目。

dateFormat = %A, %B %e

使用 L10N_Date 库中的 formatLocale 方法,这将返回
“完整星期几名称” “完整月份名称” “月份中的日期”(星期四 1 月 29 日)。法语版本的属性文件以以下方式定义了相同的键。

dateFormat = %A %e %B

这将产生
“完整星期几名称” “月份中的日期” “完整月份”(星期四 25 月 1 日)。

包含 L10n_Date 库时,mozL10n 对象(navigator.mozL10n.DateTimeFormat())将提供一个新方法。实例化此对象后,它将具有几个可用于本地化日期的方法。最有用的方法是

localeFormat 方法

localeFormat 方法接受一个日期对象参数和一个格式模式参数,并返回以模式中指定的格式格式化的日期。此方法应与 L10N.js get 方法结合使用以格式化本地化的日期。

button3.onclick = function () {
    navigator.mozL10n.language.code = "fr";
    navigator.mozL10n.ready( function() {
        var d = new Date();
        var f = new navigator.mozL10n.DateTimeFormat();
        var format = navigator.mozL10n.get('dateFormat');
        var formatted = f.localeFormat(d, format);
        alert( formatted );
    });
}

localeDateString、localeTimeString 和 localeString 方法

这三个方法只是 localeFormat 方法的变体,它们根据日期属性文件中的以下键值返回格式化的日期。

//en-US
//localeString returns
dateTimeFormat_%c = %a %b %e %Y %I:%M:%S %p
//localeDateString returns
dateTimeFormat_%x = %m/%d/%Y
//localeTimeString rerturns
dateTimeFormat_%X = %I:%M:%S %p

fromNow 方法

fromNow 方法接受一个日期/时间参数,并返回一个本地化格式的字符串,表示当前日期/时间与传入的日期/时间之间的差异。格式化后的字符串将基于日期属性文件中定义的字符串。例如

//Executed on 7/25/2013 12:11:00
var d = new Date("July 25, 2013 11:13:00");
var f = new navigator.mozL10n.DateTimeFormat();
alert( f.fromNow(d));

将在 en-US 语言环境中提醒“58 分钟前”。字符串将使用日期属性文件中的 minutes-ago-long 键进行格式化。

minutes-ago-long={[ plural(value) ]}
minutes-ago-long[zero] = just now
minutes-ago-long[one] = a minute ago
minutes-ago-long[two] = {{value}} minutes ago
minutes-ago-long[few] = {{value}} minutes ago
minutes-ago-long[many] = {{value}} minutes ago
minutes-ago-long[other] = {{value}} minutes ago

了解更多,并参与进来!

有关良好本地化实践的进一步阅读,请参阅 Mozilla 开发者网络文章,“创建可本地化的网络应用程序。

在完成您自己的 Firefox OS 应用的本地化后,为什么不帮助本地化 Firefox OS 本身?查看此 链接 以了解更多有关如何贡献的信息。

关于 Robert Nyman [资深编辑]

技术布道者和 Mozilla Hacks 编辑。发表演讲并撰写有关 HTML5、JavaScript 和开放网络的博客文章。Robert 是 HTML5 和开放网络的坚定支持者,自 1999 年以来一直致力于网络前端开发 - 在瑞典和纽约市。他还经常在 http://robertnyman.com 上写博客,并且喜欢旅行和结识新朋友。

更多来自 Robert Nyman [资深编辑] 的文章…


10 条评论

  1. goofy

    非常感谢这份清晰的本地化指南,我希望它能成为某种“官方”的 Mozilla 建议,供那些经常在*之后*才想到本地化的网络应用开发者使用。作为一个本地化人员,我很高兴看到最终的语言环境格式是 .properties。您是否计划将这篇博文的內容推送到 MDN 上?它可能非常有用。

    2013 年 8 月 22 日 下午 09:36

  2. Chris Mills

    作为负责应用程序和 FxOS 文档的 MDN 编辑,@goofy 可以自信地说,我们会为这篇文章和其他类似的精彩内容找到一个家,这些内容应该保留在 MDN 上。 我很快就会着手移植这篇文章。

    2013 年 8 月 22 日 上午 10:22

  3. niutech

    为什么不使用一些基于 JSON 的本地化库,比如 jQuery.localize 或者 Mozilla 的 i18njs: http://blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with-a-little-help-from-json-and-the-server/

    2013 年 8 月 22 日 下午 3:08

    1. Jason Weathersby

      这些方法也是完全有效的。

      2013 年 8 月 26 日 上午 8:42

  4. Peter Rukavina

    提供一些关于如何最好地处理阿拉伯语等 RTL 语言的指导将很有帮助。 我不太清楚默认的 Gaia 应用程序是如何处理这个问题的。

    2013 年 8 月 25 日 下午 12:38

  5. Peter Rukavina

    以上代码中有一个错别字

    navaigator.mozL10n.language.direction // 返回 rtl 或 ltr

    应该是

    navigator.mozL10n.language.direction // 返回 rtl 或 ltr

    2013 年 8 月 26 日 上午 5:55

  6. Peter Rukavina

    好的,以下是我如何设置语言方向(前提是存在 jQuery)

    $(document).ready(function() {
    $(“html”).attr(“dir”,navigator.mozL10n.language.direction);
    });

    2013 年 8 月 26 日 上午 6:03

    1. Jason Weathersby

      感谢您的更新。 我已经修复了这篇文章。

      2013 年 8 月 26 日 上午 8:41

  7. Abin Abraham

    我们能用这些方法将语言本地化为印地语、乌尔都语等 Unicode 语言吗?

    如果是的话,操作系统内核如何转换这些 Unicode 消息?

    2013 年 8 月 26 日 下午 7:21

  8. Jason Weathersby

    我相信在 8 月下旬,对属性文件进行了更改,以更好地支持 Unicode 字符。
    https://bugzilla.mozilla.org/show_bug.cgi?id=898316

    2013 年 8 月 27 日 上午 8:29

本文的评论已关闭。