使用 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 是 Singleton 物件,可以定義用來使用和管理已當地語系化之資源的方法和屬性。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

為應用程式傳回 Singleton 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 當地語系化架構可支援這兩個字元)。

您可以將任意數目的資源檔加入至地區子目錄。通常,您必須為每個語言建立當地語系化檔案 (並將檔案置於該語言所代表的目錄中)。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 特質會使用預設屬性檔案 (default.properties) 中為 mainWindowTitle 索引鍵所定義的值:

<title local_innerHTML="default.mainWindowTitle"/>

如果目前的地區未定義任何相符的值,Localizer 架構便會搜尋地區鍊的其餘部分。它會使用地區鍊中的下一個已定義值所代表的地區。

在下列範例中, p 元素的文字 ( innerHTML 特質) 會使用預設屬性檔案中定義之 greeting 索引鍵的值:

<p local_innerHTML="default.greeting" />

在下列範例中, input 元素的 value 特質 (和已顯示的文字) 會使用預設屬性檔案中定義之 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_" 特質的值。例如,在上一個範例中,假設當地語系化架構 (在地區鍊的所有 default.properties 檔案中) 找不到 lblColors 索引鍵的值。在這個情況下,這個架構會使用 "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 參數的值可以是下列任何類型:

  • String,定義應用程式目錄 (例如 "locales" ) 的相對路徑

  • String,定義使用 app app-storage file URL 配置 (例如 "app://languages" ,請「不要」使用 http URL 配置) 的有效 URL

  • File 物件

如需 URL 與目錄路徑的相關資訊,請參閱:

例如,在下列程式碼中,會將組合包目錄設定為應用程式儲存目錄 (而非應用程式目錄) 的 languages 子目錄:

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

請傳遞有效的路徑做為 path 參數,否則,這個方法會擲回 BundlePathNotFoundError 例外。這個錯誤的 name 屬性為 "BundlePathNotFoundError" ,而且其 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() 方法會傳回 Array,它會列出目前地區鍊中的所有地區。

下列程式碼會讀取目前的地區鍊,並將兩個法文地區加入至地區鍊的標頭:

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 中使用字串,或者在函數呼叫中,將字串當做參數值使用。例如,下列程式碼會呼叫 alert() 函數時,搭配在 fr_FR 地區之預設屬性檔案的 error114 資源中定義的字串:

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); 
}