小工具和国际化 (i18n)

本文档介绍了如何创建易于为国际用户本地化的小工具。

目录

  1. 简介
  2. 基本概念
  3. 国际化编码
  4. 实例
  5. 创建本地化的小工具
  6. 消息包
    1. 命名约定
    2. 最佳实践
  7. 在小工具中使用消息包
    1. 消息退回
    2. 从消息包访问消息
    3. 在小工具 HTML 中显示消息
  8. “Hello World”小工具规范
  9. 创建双向小工具
    1. 更改小工具的部分的方向
  10. 测试
  11. 缓存
  12. 疑难解答

简介

小工具 API 提供了一种简单方法以使国际用户可以使用您的小工具。这种方法很简单:您需要做的就是构建小工具,以便用户可见文本(应翻译的所有文本)显示在与小工具分离的消息包中。然后,第三方翻译者将翻译您的字符串,并创建新的区域特定的消息包(将添加至小工具规范)。这样,小工具便可供新用户组使用了。

有关使用非英语小工具的讨论,请参阅“非英语小工具”

基本概念

本文档参考了国际化 (i18n) 和本地化 (l10n):

  • I18n 是指以可本地化应用程序的方式构建应用程序。
  • L10n 是指使应用程序可用于特定市场,如讲法语的加拿大市场。

为实现本文档目的,用户的“本地化配置文件”包含两个部分:国家/地区(基于用户的域)和首选的用户界面语言(请参阅“测试”以获取详细信息)。

国际化编码

小工具 API 支持对 XML 属性值进行 UTF-8 编码以及在 <Content> 部分中进行 UTF-8 编码。如果您的内容类型设置为 html,则 UTF-8 将明确设置为默认的编码。您不应尝试自己进行设置。

实例

本文档中使用的实例小工具显示消息“你好世界”(在此处以中文显示):

Hello World-Chinese

在本实例中,用户可以通过用户使用偏好下拉菜单为“Hello World”消息指定字体颜色。菜单中显示的颜色名称在外部文件(消息包)中定义。显示菜单的语言取决于用户的国家/语言配置文件。如果是使用英语配置文件的用户运行该小工具,则文本以英语显示。以下是显示下拉用户使用偏好菜单的英语版实例的外观:

Hello World-English

您可以在此处查看“Hello World”的小工具规范。

创建本地化的小工具

要创建本地化的小工具,基本步骤如下:

  1. 编写小工具。
  2. 提取需要翻译为消息包的所有文本。
  3. 寻找能帮您翻译小工具的人员。
  4. 翻译者为特定区域创建新的消息包。可以按语言(法语)也可以按语言/国家(法语/加拿大、法语/法国)进行创建。请注意,非英语消息包必须以 UTF-8 格式保存。
  5. 翻译者将新消息包的网址发送给您。
  6. 修改小工具规范以使用消息包。
  7. 如果您的小工具在内容目录中,请等待 1 至 2 周以便抓取器和管线找到更新的小工具并使之在新市场中可用。

消息包

小工具 i18n 策略以消息包为核心。消息包是包含给定区域的翻译字符串的 XML 文件。每个字符串均以消息包中统一的唯一名称标识。

消息包可以托管在任意网址中,也可以在应用程序间共享。消息包只包含一个区域。

消息包的格式如下:

<messagebundle>
  <msg name="hello_world"> 
    Hello World. 
  </msg> 
  <msg name="color">Color</msg> 
  <msg name="red">Red</msg> 
  <msg name="green">Green</msg> 
  <msg name="blue">Blue</msg> 
  <msg name="gray">Gray</msg> 
  <msg name="purple">Purple</msg> 
  <msg name="black">Black</msg> 
</messagebundle> 

消息包文件中可能包含的字段如下所示:

  • messagebundle:用于翻译的消息组。
  • msg:部分可翻译的内容,通常是标签、句子甚至是段落。
  • msg name:每条消息的用户可读 ID。

命名约定

按照约定,消息包如下命名:

<language>_<country>.xml 

如果没有语言特定或国家/地区特定的值,则约定将使用“ALL”。例如,文件 de_ALL.xml 适用于所有讲德语的人,无论其属于哪个国家/地区。消息包 ALL_ALL.xml默认使用的文件。

最佳实践

没有严格要求遵循消息包命名约定。小工具使用 <Locale>langcountry属性来为用户的个人资料标识正确的消息包。它不使用消息包本身的名称。

不过,虽然小工具 API 给予您很大的灵活性,我们仍建议您遵循以下指导方针:

  • 始终提供 ALL_ALL.xml 消息包进行默认的消息处理。
  • 为每种语言指定一个区域。即,使用 fr_ALLde_ALL 等等。
  • 如果您需要进行区域特定的覆盖,请使用语言-国家/地区消息包。例如,如果您希望提供加拿大英语消息包覆盖 en_ALL,请使用 en_CA 而不是 ALL_CA

在小工具中使用消息包

您可以使用 <Locale> 标签(嵌套在 <ModulePrefs> 部分内)来列出小工具使用的消息包。例如:

<ModulePrefs title="i18n Example"> 
  <Locale messages="http://doc.examples.googlepages.com/ALL_ALL.xml"/> 
  <Locale lang="de" messages="http://doc.examples.googlepages.com/de_ALL.xml"/> 
  <Locale lang="zh-cn" messages="http://doc.examples.googlepages.com/zh_cn_ALL.xml"/> 
  <Locale lang="fr" messages="http://doc.examples.googlepages.com/fr_ALL.xml"/> 
  <Locale lang="ja" messages="http://doc.examples.googlepages.com/ja_ALL.xml"/> 
  <Locale lang="es" messages="http://doc.examples.googlepages.com/es_ALL.xml"/> 
  <Locale lang="it" messages="http://doc.examples.googlepages.com/it_ALL.xml"/> 
  <Locale lang="ru" messages="http://doc.examples.googlepages.com/ru_ALL.xml"/> 
</ModulePrefs>

<Locale> 可能具有以下属性:

  • messages:通过网址访问的消息包。
  • lang:消息包已翻译至的语言。
  • country:“Hello World”小工具规范中没有此属性的实例,但您也可以指定国家/地区属性。例如,该消息包适用于讲法语的加拿大用户:
<Locale lang="fr" country="CA" messages="http://example.com/fr_CA.xml"/> 

运行时,小工具使用与用户个人资料最近似匹配的消息包。

语言的有效值是 ISO639-1 两位语言代码,国家/地区的有效值是 ISO 3166-1 alpha-2 代码。

消息退回

消息包具有退回功能。利用消息退回,小工具可尝试使用与用户的国家/地区和语言 UI 使用偏好(在网址中指定)最近似匹配的消息包。如果小工具找不到完全匹配的消息包,则会在可用的消息包中“退回”以查找最近似匹配的消息包。

利用消息退回,您可以在给定区域不可使用某消息时使用“默认”消息(通常在 ALL_ALL.xml 中指定)。

例如,假设您在小工具中指定了以下内容:

<Locale messages="http://x.com/ALL_ALL.xml"/> 
<Locale lang="de" messages="http://x.com/de_ALL.xml"/>
<Locale lang="de" country="DE" messages="http://x.com/de_DE.xml"/> 
<Locale lang="de" country="US" messages="http://x.com/de_US.xml"/>

将如何使用这些文件?假设您有位用户,其域为美国 (http://www.google.com),而其语言使用偏好是德语。她将从 de_US.xml 文件中查看消息。如果无法从该文件获得特定的消息,她将从 de_ALL.xml 中查看消息;如果无法从该文件获得特定的消息,她最后将从 ALL_ALL.xml 中查看消息。

使用德语 UI 的德国用户从 de_DE.xml 开始,使用德语 UI 的瑞士用户从 de_ALL.xml 开始,而使用法语 UI 的瑞士用户从 ALL_ALL.xml 开始。

从消息包访问消息

小工具如何访问消息包中的相应消息?假设 de_ALL.xml(德语,国家 ALL)文件在“Hello World”实例中:

<messagebundle>
  <msg name="hello_world">
    Hallo Welt.
  </msg>
  <msg name="color">Farbe</msg> 
  <msg name="red">Rot</msg> 
  <msg name="green">Grün</msg> 
  <msg name="blue">Blau</msg> 
  <msg name="gray">Grau</msg> 
  <msg name="purple">Purpurrot</msg> 
  <msg name="black">Schwarz</msg>
</messagebundle>

每条消息都有标识它的唯一名称字符串。例如,在此消息中:

<msg name="red">Rot</msg> 

唯一的消息名称是“red”,小工具中显示的翻译字符串(在其用户使用偏好下拉菜单中)是“Rot”(“red”的德语单词)。以下是消息包 ALL_ALL.xml 中对等的英语消息字符串:

<msg name="red">Red</msg> 

“Hello World”小工具规范使用 __MSG_ 替换变量来标识相应消息包中应替换值的地方。例如,“Hello World”小工具规范中的该 XML 语句用于向用户使用偏好“颜色”下拉菜单添加菜单项:

<EnumValue value="Red" display_value="__MSG_red__" /> 

实际上,该行的意思是“转至与用户国家/语言配置文件最匹配的消息包,获取名为‘red’的消息的值,并用 __MSG_red__ 替换它”。这是使用颜色名称(在此处以德语显示)填充“Hello World”实例中的用户使用偏好下拉菜单的方式:

Hello World-German

在小工具 HTML 中显示消息

要在小工具的 XML 部分中显示消息,请按照上述说明使用替换变量。在小工具的 CDATA 部分中,您可有多种不同选择。

最简单的技术是将替换变量嵌入 HTML 中:

<b>__MSG_hello_world__</b>. 

或者,您可以使用用户使用偏好函数 getMsg()。请注意,该函数可用来访问消息包中的所有消息,而不只是与用户使用偏好相关的消息。但是,您必须在 Prefs 对象上调用该函数。例如:

var prefs = new gadgets.Prefs();
prefs.getMsg(“red”);

“Hello World”小工具规范

以下是“Hello World”实例的小工具规范:

<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs title="i18n Example"> 
    <Locale messages="http://doc.examples.googlepages.com/ALL_ALL.xml"/>
    <Locale lang="de" messages="http://doc.examples.googlepages.com/de_ALL.xml"/>
    <Locale lang="zh-cn" messages="http://doc.examples.googlepages.com/zh_cn_ALL.xml"/>
    <Locale lang="fr" messages="http://doc.examples.googlepages.com/fr_ALL.xml"/>
    <Locale lang="ja" messages="http://doc.examples.googlepages.com/ja_ALL.xml"/>
    <Locale lang="es" messages="http://doc.examples.googlepages.com/es_ALL.xml"/>
    <Locale lang="it" messages="http://doc.examples.googlepages.com/it_ALL.xml"/>
    <Locale lang="ru" messages="http://doc.examples.googlepages.com/ru_ALL.xml"/> 
  </ModulePrefs>
  <UserPref name="fontcolor" display_name="__MSG_color__" default_value="Red" datatype="enum">
    <EnumValue value="Red" display_value="__MSG_red__" /> 
    <EnumValue value="Green" display_value="__MSG_green__" /> 
    <EnumValue value="Blue" display_value="__MSG_blue__" /> 
    <EnumValue value="Gray" display_value="__MSG_gray__" /> 
    <EnumValue value="Purple" display_value="__MSG_purple__" /> 
    <EnumValue value="Black" display_value="__MSG_black__" /> 
  </UserPref>
  <Content type="html">
  <![CDATA[
    <div id="content_div"></div>
    <script type="text/javascript"> 
      // Display message in the user's preferred language
      function displayMsg(){
        var div = document.getElementById('content_div');
        // Get userprefs
        var prefs = new gadgets.Prefs();
        // Set font color to user's color choice
        div.style.color = prefs.getString("fontcolor");
        // Display message
        var html = "<br><h1>";
        // Use prefs.getMsg to go to the appropriate message bundle
        // and get the string associated with the "hello_world" message.
        html += prefs.getMsg("hello_world");
        html +=  "</h1>"; 
        div.innerHTML = html;
      }
      gadgets.util.registerOnLoadHandler(displayMsg);
    </script>
  ]]>
  </Content>
</Module>

创建双向小工具

您可以使用小工具 BIDI(双向)API 来动态更改小工具的方向。“方向”是指内容显示的方向:从左到右,或从右到左。请注意这不同于对齐方式。例如,您可能有英语文本右对齐的小工具,但文本自身的方向仍然是从左到右。

使用 BIDI API 能够编写既支持从右到左的语言(如希伯来语和阿拉伯语)、又支持从左到右的语言(如英语)的小工具。BIDI API 包括以下内容:

  • <Locale...> 标签下的language_direction属性。其值可以是“rtl”(从右到左)也可以是“ltr”(从左到右)。您可以使用该属性来设置小工具的方向。默认情况下,小工具方向为从左到右。
  • 其值随小工具的方向而变化的 __BIDI_... 替换变量集。例如,变量 __BIDI_DIR__ 在小工具处于从左到右模式时的值为“ltr”,在小工具处于从右到左模式时的值为“rtl”。

在最简单的情况下,您可以使用 <Locale... language_direction="rtl"> 来静态设置小工具的方向。例如,该小工具仅显示希伯来语文本,所以其方向总是设置为从右到左:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="כותרת two-כיוונית"        
    height="100">
    <Locale lang="ALL" language_direction="rtl" />
  </ModulePrefs>
  <Content type="html"><![CDATA[
    אני כותב מימין לשמאל ולא הייתי צריך להגדיר 
    dir=rtl בשביל זה!<br>
  ]]>
  </Content>
</Module>

然而,假设您的小工具包含的消息包既支持从左到右的语言又支持从右到左的语言,您将如何设计小工具来支持这两种情况?以下是根据为用户区域载入的消息包来动态更改方向的小工具的实例。该小工具拥有支持两种从右到左的语言(希伯来语 [iw] 和阿拉伯语 [ar])的消息包:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="BIDI Hello World">
    <Locale messages="http://doc.examples.googlepages.com/ALL_ALL.xml"/>
    <Locale lang="ru" messages="http://doc.examples.googlepages.com/ru_ALL.xml"/>
    <Locale lang="fr" messages="http://doc.examples.googlepages.com/fr_ALL.xml"/>
    <Locale lang="ja" messages="http://doc.examples.googlepages.com/ja_ALL.xml"/>
    <Locale lang="es" messages="http://doc.examples.googlepages.com/es_ALL.xml"/>
    <Locale lang="it" messages="http://doc.examples.googlepages.com/it_ALL.xml"/>
    <Locale lang="iw" messages="http://doc.examples.googlepages.com/iw_ALL.xml" language_direction="rtl"/>
    <Locale lang="ar" messages="http://doc.examples.googlepages.com/ar_ALL.xml" language_direction="rtl"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <div style="margin-__BIDI_START_EDGE__:30px;"><h2>__MSG_hello_world__</h2></div>
  ]]>
  </Content>
</Module>

对于该小工具,假设用户的语言使用偏好是“阿拉伯语”。行 <Locale lang="ar" messages="http://.../ar_ALL.xml" language_direction="rtl"/> 的意思是“对于阿拉伯语,显示消息包 ar_ALL.xml 中的文本,并将小工具的方向设置为 rtl”。对于希伯来语,该方向也可设置为从右到左。对于其他语言,小工具方向暗中设置为默认的 ltr(从左到右)。

<div style="margin-__BIDI_START_EDGE__:30px;"><h2>__MSG_hello_world__</h2></div> 的意思是“当小工具处于从左到右模式时,文本从边界偏移 30 像素。当小工具处于从右到左模式时,文本从边界偏移 30 像素”。例如,如果用户的浏览器设置为“阿拉伯语”(从右到左),则以下便是在运行时进行替换的方式:

<div style="margin-right:30px;"><h2>أهلاً بالعالم</h2></div>

该表列出了 BIDI 替换变量及其可能值。请注意,它们的值始终与小工具自身的方向相关。换言之,这些变量是专门为与 <Locale... language_direction="..."> 设置配合使用而设计的。您可以在小工具正文内的任意位置使用这些变量。

变量 说明
__BIDI_START_EDGE__ 该变量表示小工具内容显示起始点的一侧。当小工具处于 LTR 模式时,该值为“左”;当小工具处于 RTL 模式时,该值为“右”。上述小工具给出了使用该变量进行 CSS 边界设置的实例。
__BIDI_END_EDGE__ 该变量表示与内容显示起始处相对的小工具边界。当小工具处于 LTR 模式时,该值为“右”;当小工具处于 RTL 模式时,该值为“左”。
__BIDI_DIR__ 当小工具处于 LTR 模式时,该变量的值为“ltr”;当小工具处于 RTL 模式时,其值为“rtl”。
__BIDI_REVERSE_DIR__ 当小工具处于 LTR 模式时,该变量的值为“rtl”;当小工具处于 RTL 模式时,其值为“ltr”。

更改小工具的部分的方向

BIDI API 是专门为更改整个小工具的方向,以及相应地格式化小工具的内容而设计的。但是,有些时候,您可能想在小工具内调整文本中单独行的方向。您可能不希望小工具的方向与用户的语言设置或任意特定语言绑定在一起。例如,您可以创建可同时显示英语和希伯来语文本的小工具。也可以创建列出各种语言的常用短语的小工具。您可以使用常规的 DOM 函数调用和 CSS 来设置小工具正文内的文本方向。例如:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="DOM Hello World" height="200" />

  <Content type="html"><![CDATA[
  <script type="text/javascript">
  // In this gadget, users choose a language from a drop-down menu, and the gadget displays
  // a "Hello World" message for the selected language. The gadget uses DOM functions to set 
  // the direction and formatting for the message, depending on whether its language is RTL 
  // or LTR.
  // Associative array containing "Hello World" messages for different languages
  var msgs = new Object();
  msgs = {
    "English" : "Hello World",
    "Hebrew"  : "שלום עולם",
    "French"  : "Bonjour Monde",
    "Arabic"  : "أهلاً بالعالم",
    "Russian" : "Здравствуйте Мир!"
    };
  
  function showMsg() {
    var html="<h1>";
    var div = _gel('mydiv');
    div.style.color = "green";
    var index = document.myform.Language.selectedIndex;
    var lang = document.myform.Language.options[index].text;
    var str = msgs[lang];    
    if (!str)
       str="";
    // If language is Hebrew or Arabic, set the div direction to be right-to-left.
    // Offset text 30px from right margin.
    if(lang=="Hebrew" || lang=="Arabic") {
      div.style.direction = "rtl";
      div.style.marginRight = "30px";
      html += str;
    }
    // For other languages, set div direction to left-to-right.
    // Offset text 30px from left margin.
    else {
      div.style.direction = "ltr";
      div.style.marginLeft = "30px";
      html += str;
    }
    html+= "</h1>";
    div.innerHTML = html;
  }
  </script>
  <div style="background-color: #BFCFFF; height: 200px; color:green;">
    <br />
    <div>
      <form name="myform" style="text-align: center;">
        <select name="Language" onchange="showMsg()">
          <option>Pick a Language
          <option>English
          <option>Hebrew
          <option>French
          <option>Arabic
          <option>Russian
        </select>
      </form>
    </div>
    <br />
    <div id="mydiv"><h2 style='text-align: center;'>****Pick a language****</h2></div>
  </div>
  ]]>
  </Content>
</Module>

测试

要测试小工具,您可以更改国家/地区和语言设置来与小工具包含的消息包相对应。

在 iGoogle 中更改国家/地区和语言设置的最简单方法是编辑网址:

http://www.google.com/ig?&gl=<country>&hl=<lang>

例如,在以下网址中,国家/地区是德国 (DE) 而语言是英语 (en)。一般来说,国家/地区的优先级高于语言,因此在该网址中,iGoogle 以德语显示文本:

http://www.google.com/ig?&gl=DE&hl=en

在该实例中,国家/地区无疑为美国而语言是西班牙语:

http://www.google.com/ig?hl=es

您可以使用以下链接来帮助为特定语言构建正确的网址:http://www.google.com/help/customize.html#searchlang。语言的有效值是 ISO639-1 两位语言代码,国家/地区的有效值是 ISO 3166-1 alpha-2 代码。

缓存

消息包的缓存行为与小工具规范自身的缓存行为相同:我们通常每 1 至 2 小时刷新一次缓存,托管服务器每天应仅查看 ~100 至 200 个消息包请求,如果无法获得,我们将尽可能继续使用“旧”版本。在 developer.xml 小工具中,如果禁用小工具的缓存,则也会禁用小工具的消息包的缓存。

疑难解答

在开发过程中,您可能会发现小工具在应显示消息的位置或者显示空白或者显示 ???。其原因可能是:

  • 您没有将消息包保存为 UTF-8。这对于包含特殊字符的所有非英语语言文件都是必要的。
  • 消息包语法有问题。
  • 您没有默认情况下供小工具使用的 ALL_ALL.xml 消息文件。
  • 您小工具中消息包的网址不正确。
  • 消息包与您在小工具中指定的消息替换变量不匹配。

返回页首