使用 AIR HTML 本地化框架本地化 HTML 内容

Adobe AIR 1.1 和更高版本

AIR 1.1 SDK 包括一个 HTML 本地化框架。AIRLocalizer.js JavaScript 文件定义了该框架。AIR SDK 的 frameworks 目录包含 AIRLocalizer.js 文件。该文件包含一个 air.Localizer 类,该类提供了帮助创建可支持多个本地化版本的应用程序的功能。

加载 AIR HTML 本地化框架代码

若要使用本地化框架,请将 AIRLocalizer.js 文件复制到您的项目中。然后使用 script 标签将其包括在应用程序的主要 HTML 文件中:

<script src="AIRLocalizer.js" type="text/javascript" charset="utf-8"></script>

后续的 JavaScript 可以调用 air.Localizer.localizer 对象:

<script> 
    var localizer = air.Localizer.localizer; 
</script>
air.Localizer.localizer 对象是定义使用和管理本地化资源的方法和属性的单个对象。Localizer 类包含以下方法:

方法

说明

getFile()

获取指定区域设置的指定资源包。请参阅 获取特定区域设置的资源 。

getLocaleChain()

返回区域设置链中的语言。请参阅 定义区域设置链 。

getResourceBundle()

将捆绑密钥和相应的值作为对象返回。请参阅 获取特定区域设置的资源 。

getString()

获取为资源定义的字符串。请参阅 获取特定区域设置的资源 。

setBundlesDirectory()

设置包目录的位置。请参阅 自定义 AIR HTML Localizer 设置 。

setLocalAttributePrefix()

设置由用于 HTML DOM 元素中的 localizer 属性使用的前缀。请参阅 自定义 AIR HTML Localizer 设置

setLocaleChain()

设置区域设置链中语言的顺序。请参阅 定义区域设置链 。

sortLanguagesByPreference()

基于操作系统设置中区域设置的顺序,对区域设置链中的区域设置进行排序。请参阅 定义区域设置链 。

update()

使用当前区域设置链中的本地化字符串更新 HTML DOM(或 DOM 元素)。有关区域设置链的说明,请参阅 管理区域设置链 。有关 update() 方法的详细信息,请参阅 更新 DOM 元素以使用当前区域设置 。

Localizer 类包含以下静态属性:

属性

说明

localizer

返回对应用程序单个 Localizer 对象的引用。

ultimateFallbackLocale

应用程序不支持用户首选参数时使用的区域设置。请参阅 定义区域设置链 。

指定支持的语言

使用应用程序描述符文件中的 <supportedLanguages> 元素识别应用程序支持的语言。此元素仅用于 iOS、Mac 捕获运行时和 Android 应用程序,所有其他应用程序类型将忽略此元素。

如果您不指定 <supportedLanguages> 元素,包装程序将默认根据应用程序类型执行以下操作:

  • iOS — AIR 运行时支持的所有语言均作为应用程序的支持语言列在 iOS App Store 中。

  • Mac 捕获运行时 — 使用捕获捆绑打包的应用程序没有本地化信息。

  • Android — 应用程序包包括 AIR 运行时支持的所有语言的资源。

有关详细信息,请参阅 supportedLanguages 。

定义资源包

HTML 本地化框架从 本地化 文件中读取字符串的本地化版本。本地化文件是文本文件中经过序列化的基于键的值集合。本地化文件有时被称为 包 。

创建一个名为 locale 的应用程序项目目录的子目录。(您也可以使用其他名称,请参阅 自定义 AIR HTML Localizer 设置 。)该目录将包括本地化文件。该目录被称为 包目录 。

针对应用程序支持的每个区域设置,都创建一个包目录的子目录。命名每个子目录以与区域设置代码相匹配。例如,将法语目录命名为“fr”并将英语目录命名为“en”。您可以使用下划线 (_) 字符定义具有语言和国家/地区代码的区域设置。例如,将美式英语目录命名为“en_us”。(也可以使用连字符代替下划线,如“en-us”。HTML 本地化框架支持这两种形式。)

您可以向 locale 子目录添加任意数目的资源文件。通常,为每种语言均创建一个本地化文件(并将该文件放在该语言的目录中)。HTML 本地化框架包括一个 getFile() 方法,利用该方法可以读取文件的内容(请参阅 获取特定区域设置的资源 。

具有 .properties 文件扩展名的文件被认为是本地化属性文件。可以使用这些文件为区域设置定义键值对。属性文件在每行都定义了一个字符串值。例如,以下定义了一个字符串值 "Hello in English." ,针对名为 greeting 的键:

greeting=Hello in English.

包含以下文本的属性文件定义了六个键值对:

title=Sample Application 
greeting=Hello in English. 
exitMessage=Thank you for using the application. 
color1=Red 
color2=Green 
color3=Blue

此示例显示了要存储在 en 目录中的属性文件的英语版本。

此属性文件的法语版本放置在 fr 目录中:

title=Application Example 
greeting=Bonjour en français. 
exitMessage=Merci d'avoir utilisé cette application. 
color1=Rouge 
color2=Vert 
color3=Bleu

您可以为不同种类的信息定义多个资源文件。例如,legal.properties 文件可能包含法律文本样本(如版权信息)。您可以在多个应用程序中重复使用该资源。同样,您可以定义单独的文件为用户界面的不同部分定义本地化内容。

对这些文件使用 UTF-8 编码以支持多种语言。

管理区域设置链

当应用程序加载 AIRLocalizer.js 文件时,该文件将检查应用程序中定义的区域设置。这些区域设置对应于包目录的子目录(请参阅 定义资源包 )。此可用区域设置的列表称为 区域设置链 。AIRLocalizer.js 文件将根据操作系统设置定义的首选顺序自动对区域设置链进行排序。( Capabilities.languages 属性按首选顺序列出操作系统用户界面语言。)

因此,如果应用程序为“en”、“en_US”和“en_UK”区域设置定义了资源,则 AIR HTML Localizer 框架将对区域设置链进行相应排序。当应用程序在将“en”报告为主区域设置的系统中启动时,区域设置链的排序顺序为 ["en", "en_US", "en_UK"] 。此时,应用程序首先在“en”包中查找资源,然后在“en_US”包中查找。

但是,如果系统将“en-US”报告为主区域设置,则排序将使用 ["en_US", "en", en_UK"] 。在此情况下,应用程序首先在“en_US”包中查找资源,然后在“en”包中查找。

默认情况下,应用程序会将区域设置链中的第一个区域设置定义为要使用的默认区域设置。您可以请用户在第一次运行应用程序时选择一个区域设置。然后,您可以选择将该选择存储在首选参数文件中,并在随后的应用程序启动中使用该区域设置。

应用程序可以在区域设置链中的任何区域设置中使用资源字符串。如果特定区域设置未定义资源字符串,则应用程序将为区域设置链中定义的其他区域设置使用下一个匹配的资源字符串。

可以通过调用 Localizer 对象的 setLocaleChain() 方法自定义区域设置链。请参阅 定义区域设置链 。

利用本地化的内容更新 DOM 元素

应用程序中的元素可以引用本地化属性文件中的键值。例如,以下示例中的 title 元素指定了 local_innerHTML 属性。本地化框架使用此属性查找本地化值。默认情况下,框架会查找以 "local_" 开头的属性名称。该框架将更新名称与 "local_" 之后的文本相匹配的属性。在本例中,框架会设置 title 元素的 innerHTML 属性。 innerHTML 属性 (attribute) 将在默认属性 (property) 文件 (default.properties) 中使用为 mainWindowTitle 键定义的值:

<title local_innerHTML="default.mainWindowTitle"/>

如果当前区域设置未定义匹配的值,则 localizer 框架将搜索区域设置链的其余部分。该框架将使用区域设置链中定义了值的下一个区域设置。

在以下示例中, p 元素的文本( innerHTML 属性 (attribute))使用在默认属性 (property) 文件中定义的 greeting 键的值:

<p local_innerHTML="default.greeting" />

在以下示例中, input 元素的值属性 (attribute)(和显示文本)使用默认属性 (property) 文件中定义的 btnBlue 键的值:

<input type="button" local_value="default.btnBlue" />

若要更新 HTML DOM 以使用当前区域设置链中定义的字符串,请调用 Localizer 对象的 update() 方法。调用 update() 方法将使 Localizer 对象分析 DOM 并在其找到本地化 ( "local_..." ) 属性处应用操作:

air.Localizer.localizer.update();

您可以为属性(如“innerHTML”)及其相应的本地化属性(如“local_innerHTML”)都定义值。在这种情况下,如果本地化框架在本地化链中找到一个匹配值,则仅覆盖该属性值。例如,以下元素定义了 value 和 local_value 属性:

<input type="text" value="Blue" local_value="default.btnBlue"/>

也可以只更新特定的 DOM 元素。请参阅下一节 更新 DOM 元素以使用当前区域设置 。

默认情况下,AIR HTML Localizer 使用 "local_" 作为定义元素的本地化设置的属性前缀。例如,默认情况下, local_innerHTML 属性定义了用于元素的 innerHTML 值的包和资源名称。同样,默认情况下, local_value 属性定义了用于元素的 value 属性的包和资源名称。您可以将 Localizer 配置为使用除 "local_" 之外的属性前缀。请参阅 自定义 AIR HTML Localizer 设置 。

更新 DOM 元素以使用当前区域设置

当 Localizer 对象更新 HTML DOM 时,将导致已标记元素根据当前区域设置链中定义的字符串使用属性值。若要使 HTML localizer 更新 HTML DOM,请调用 Localizer 对象的 update() 方法:

air.Localizer.localizer.update();

若要仅更新指定的 DOM 元素,请将其作为参数传递到 update() 方法。 update() 方法只有一个参数 parentNode ,该参数为可选参数。指定后, parentNode 参数将定义要本地化的 DOM 元素。调用 update() 方法并指定 parentNode 参数,可将为所有指定本地化属性的子元素设置本地化值。

以下面的 div 元素为例:

<div id="colorsDiv"> 
    <h1 local_innerHTML="default.lblColors" ></h1> 
    <p><input type="button" local_value="default.btnBlue" /></p> 
    <p><input type="button" local_value="default.btnRed" /></p> 
    <p><input type="button" local_value="default.btnGreen" /></p> 
</div>

若要更新此元素以使用当前区域设置链中定义的本地化字符串,请使用以下 JavaScript 代码:

var divElement = window.document.getElementById("colorsDiv"); 
air.Localizer.localizer.update(divElement);

如果并未在区域设置链中找到键值,则本地化框架将属性值设置为 "local_" 属性的值。例如,在上一个示例中,假设本地化框架无法找到 lblColors 键(在区域设置链中的任何一个 default.properties 文件中)的值。在此情况下,它将使用 "default.lblColors" 作为 innerHTML 值。使用该值指示(开发人员)缺少资源。

当 update() 方法在区域设置链中无法找到资源时,将调度 resourceNotFound 事件。 air.Localizer.RESOURCE_NOT_FOUND 常量定义了字符串 "resourceNotFound" 。该事件具有三个属性: bundleName 、 resourceName 和 locale 。 bundleName 属性是在其中未找到该资源的包的名称。 resourceName 属性是在其中未找到该资源的包的名称。 locale 属性是在其中未找到该资源的区域设置的名称。

当 update() 方法无法找到指定包时,将调度 bundleNotFound 事件。 air.Localizer.BUNDLE_NOT_FOUND 常量定义了字符串 "bundleNotFound" 。该事件具有两个属性: bundleName 和 locale 。 bundleName 属性是在其中未找到该资源的包的名称。 locale 属性是在其中未找到该资源的区域设置的名称。

update() 方法采用异步方式操作(并异步调度 resourceNotFound 和 bundleNotFound 事件)。以下代码将为 resourceNotFound 和 bundleNotFound 事件设置事件侦听器:

air.Localizer.localizer.addEventListener(air.Localizer.RESOURCE_NOT_FOUND, rnfHandler); 
air.Localizer.localizer.addEventListener(air.Localizer.BUNDLE_NOT_FOUND, rnfHandler); 
air.Localizer.localizer.update(); 
function rnfHandler(event) 
{ 
    alert(event.bundleName + ": " + event.resourceName + ":." + event.locale); 
} 
function bnfHandler(event) 
{ 
    alert(event.bundleName + ":." + event.locale); 
}

自定义 AIR HTML Localizer 设置

利用 Localizer 对象的 setBundlesDirectory() 方法可以自定义包目录路径。利用 Localizer 对象的 setLocalAttributePrefix() 方法可以自定义包目录路径并可自定义 Localizer 使用的属性值。

默认的包目录定义为应用程序目录的区域设置子目录。可以通过调用 Localizer 对象的 setBundlesDirectory() 方法指定另一个目录。此方法将使用一个以字符串形式表示的参数 path (它是所需包目录的路径)。 path 参数的值可以为以下任意值:

  • 用于定义与应用程序目录有关的路径的字符串,如 "locales"

  • 用于定义使用 app 、 app-storage 或 file URL 方案(如 "app://languages" )(请 勿 使用 http URL 方案)的有效 URL 的字符串

  • File 对象

有关 URL 和目录路径的信息,请参阅:

例如,下列代码将包目录设置为应用程序存储目录的语言子目录(而非应用程序目录):

air.Localizer.localizer.setBundlesDirectory("languages");

将有效的路径作为 path 参数传递。否则,该方法将引发 BundlePathNotFoundError 异常。该错误将 "BundlePathNotFoundError" 作为其 name 属性,而其 message 属性则指定无效的路径。

默认情况下,AIR HTML Localizer 使用 "local_" 作为定义元素的本地化设置的属性前缀。例如, local_innerHTML 属性定义了用于以下 input 元素的 innerHTML 值的包和资源名称:

<p local_innerHTML="default.greeting" />

利用 Localizer 对象的 setLocalAttributePrefix() 方法,可以使用除 "local_" 之外的属性前缀。此静态方法将使用一个参数,而该参数是要用作属性前缀的字符串。例如,以下代码将本地化框架设置为使用“loc_”作为属性前缀:

air.Localizer.localizer.setLocalAttributePrefix("loc_");

您可以自定义本地化框架使用的属性前缀。如果默认值 ( "local_" ) 与您的代码使用的另一个属性的名称冲突,则您可能希望自定义该前缀。请确保调用此方法时使用对 HTML 属性有效的字符。(例如,该值不能包含空格字符。)

有关在 HTML 元素中使用本地化属性的详细信息,请参阅 利用本地化的内容更新 DOM 元素 。

包目录和属性前缀设置在不同的应用程序会话之间不会保留。如果使用自定义包目录或属性前缀设置,请确保每次启动应用程序时对其进行设置。

定义区域设置链

默认情况下,加载 AIRLocalizer.js 代码时,它将设置默认的区域设置链。包目录和操作系统语言设置中可用的区域设置定义了该区域设置链。(有关详细信息,请参阅 管理区域设置链 。)

可以通过调用 Localizer 对象的静态 setLocaleChain( ) 方法修改区域设置链。例如,如果用户为某个特定语言指示一个首选参数,则您最好调用此方法。 setLocaleChain( ) 方法使用一个参数 chain ,该参数为一个区域设置数组,如 ["fr_FR","fr","fr_CA"] 。数组中区域设置的顺序设定了框架查找资源的顺序(在后续操作中)。如果未在链中找到第一个区域设置的资源,它将继续查找其他区域设置的资源。如果 chain 参数丢失、不是数组或为空数组,则此功能将失败并引发 IllegalArgumentsError 异常。

Localizer 对象的 getLocaleChain() 静态方法返回一个列出当前区域设置链中的区域设置的数组。

以下代码将读取当前区域设置链并将两个法语区域设置添加到链头:

var currentChain = air.Localizer.localizer.getLocaleChain(); 
newLocales = ["fr_FR", "fr"]; 
air.Localizer.localizer.setLocaleChain(newLocales.concat(currentChain));

当 setLocaleChain() 方法更新区域设置链时,将调度 "change" 事件。 air.Localizer.LOCALE_CHANGE 常量定义了字符串 "change" 。该事件具有一个 localeChain 属性,该属性为新的区域设置链中的区域设置代码数组。以下代码为此事件设置了一个事件侦听器:

var currentChain = air.Localizer.localizer.getLocaleChain(); 
newLocales = ["fr_FR", "fr"]; 
localizer.addEventListener(air.Localizer.LOCALE_CHANGE, changeHandler); 
air.Localizer.localizer.setLocaleChain(newLocales.concat(currentChain)); 
function changeHandler(event) 
{ 
    alert(event.localeChain); 
}

静态 air.Localizer.ultimateFallbackLocale 属性表示在应用程序不支持用户首选参数时所用的区域设置。默认值为 "en" 。您可以将其设置为另一个区域设置,如以下代码中所示:

air.Localizer.ultimateFallbackLocale = "fr";

获取特定区域设置的资源

Localizer 对象的 getString() 方法将返回为特定区域设置中的资源定义的字符串。调用此方法时,不必指定 locale 值。在此情况下,该方法将查看整个区域设置链并返回提供给定资源名称的第一个区域设置中的字符串。此方法具有以下参数:

参数

说明

bundleName

包含资源的包。这是不带 .properties 扩展名的属性文件的文件名。(例如,如果此参数设置为 "alerts" ,则 Localizer 代码将在名为 alerts.properties 的本地化文件中查找。

resourceName

资源名称。

templateArgs

可选。用于替换替换字符串中的编号标签的字符串数组。以调用 templateArgs 参数为 ["Raúl", "4"] 且匹配资源字符串为 "Hello, {0} You have {1} new messages." 。在此情况下,此函数将返回 "Hello, Raúl. You have 4 new messages." 。若要忽略此设置,请传递 null 值。

locale

可选。要使用的区域设置代码(如 "en" 、 "en_us" 或 "fr" )。如果提供了一个区域设置但未找到匹配值,则此方法将不会继续在区域设置链中的其他区域设置中搜索值。如果未指定任何区域设置代码,则此函数将返回区域设置链中第一个区域设置中为给定的资源名称提供值的字符串。

本地化框架可以更新标记的 HTML DOM 属性。但是,可以通过其他方式使用本地化字符串。例如,可以在某些动态生成的 HTML 中使用字符串或在函数调用中将其作为参数值。例如,以下代码将通过 fr_FR 区域设置的默认属性文件中 error114 资源内定义的字符串调用 alert() 函数:

alert(air.Localizer.localizer.getString("default", "error114", null, "fr_FR"));

当 getString() 方法在指定包中无法找到资源时,将调度 resourceNotFound 事件。 air.Localizer.RESOURCE_NOT_FOUND 常量定义了字符串 "resourceNotFound" 。该事件具有三个属性: bundleName 、 resourceName 和 locale 。 bundleName 属性是在其中未找到该资源的包的名称。 resourceName 属性是在其中未找到该资源的包的名称。 locale 属性是在其中未找到该资源的区域设置的名称。

当 getString() 方法无法找到指定包时,将调度 bundleNotFound 事件。 air.Localizer.BUNDLE_NOT_FOUND 常量定义了字符串 "bundleNotFound" 。该事件具有两个属性: bundleName 和 locale 。 bundleName 属性是在其中未找到该资源的包的名称。 locale 属性是在其中未找到该资源的区域设置的名称。

getString() 方法采用异步方式操作(并异步调度 resourceNotFound 和 bundleNotFound 事件)。以下代码将为 resourceNotFound 和 bundleNotFound 事件设置事件侦听器:

air.Localizerlocalizer.addEventListener(air.Localizer.RESOURCE_NOT_FOUND, rnfHandler); 
air.Localizerlocalizer.addEventListener(air.Localizer.BUNDLE_NOT_FOUND, bnfHandler); 
var str = air.Localizer.localizer.getString("default", "error114", null, "fr_FR"); 
function rnfHandler(event) 
{ 
    alert(event.bundleName + ": " + event.resourceName + ":." + event.locale); 
} 
function bnfHandler(event) 
{ 
    alert(event.bundleName + ":." + event.locale); 
}

Localizer 对象的 getResourceBundle() 方法为给定的区域设置返回一个指定的绑定。该方法的返回值是其属性与绑定中的键相匹配的对象。(如果应用程序找不到指定的绑定,则该方法返回 null 。)

该方法采用两个参数 — locale 和 bundleName 。

参数

说明

locale

区域设置(如 "fr" )。

bundleName

绑定名称。

例如,以下代码调用 document.write() 方法加载 fr 区域设置的默认绑定。然后,调用 document.write() 方法写入该绑定中 str1 和 str2 键的值:
var aboutWin = window.open(); 
var bundle = localizer.getResourceBundle("fr", "default"); 
aboutWin.document.write(bundle.str1); 
aboutWin.document.write("<br/>"); 
aboutWin.document.write(bundle.str2); 
aboutWin.document.write("<br/>");

getResourceBundle() 方法在找不到指定的绑定时将调度 bundleNotFound 事件。 air.Localizer.BUNDLE_NOT_FOUND 常量定义了字符串 "bundleNotFound" 。该事件具有两个属性: bundleName 和 locale 。 bundleName 属性是在其中未找到该资源的包的名称。 locale 属性是在其中未找到该资源的区域设置的名称。

Localizer 对象的 getFile() 方法将以字符串形式为给定区域设置返回包的内容。包文件将以 UTF-8 文件格式读取。此方法具有以下参数:

参数

说明

resourceFileName

资源文件的文件名(例如 "about.html" )。

templateArgs

可选。用于替换替换字符串中的编号标签的字符串数组。以调用 templateArgs 参数为 ["Raúl", "4"] 且匹配的资源文件包含以下两行的函数为例:

<html> 
<body>Hello, {0}. You have {1} new messages.</body> 
</html> 

在此情况下,此函数将返回两行字符串:

<html> 
<body>Hello, Raúl. You have 4 new messages. </body> 
</html> 
locale

要使用的区域设置代码,例如 "en_GB" 。如果提供了区域设置但未找到匹配的文件,则此方法将不会继续在区域设置链中的其他区域设置中搜索。如果 未 指定区域设置代码,则此函数将返回区域设置链中第一个区域设置中的文本,而该区域设置链具有一个与 resourceFileName 相匹配的文件。

例如,以下代码使用 fr 区域设置的 about.html 文件的内容调用 document.write() 方法:

var aboutWin = window.open(); 
var aboutHtml = localizer.getFile("about.html", null, "fr"); 
aboutWin.document.close(); 
aboutWin.document.write(aboutHtml);

当 getFile() 方法在区域设置链中无法找到资源时,将调度 fileNotFound 事件。 air.Localizer.FILE_NOT_FOUND 常量定义了字符串 "resourceNotFound" 。 getFile() 方法采用异步方式操作(并异步调度 fileNotFound 事件)。该事件具有两个属性: fileName 和 locale 。 fileName 属性为未找到的文件的名称。 locale 属性是在其中未找到该资源的区域设置的名称。以下代码为此事件设置了一个事件侦听器:

air.Localizer.localizer.addEventListener(air.Localizer.FILE_NOT_FOUND, fnfHandler); 
air.Localizer.localizer.getFile("missing.html", null, "fr"); 
function fnfHandler(event) 
{ 
    alert(event.fileName + ": " + event.locale); 
}