為了便於查看,轉載了文章,感謝作者
轉載自:https://www.ibm.com/developerworks/cn/web/1305_hezj_jqueryi18n/
在介紹 jQuery.i18n.properties 之前,我們先來看一下什么是國際化。國際化英文單詞為:Internationalization,又稱 i18n,“i”為單詞的第一個字母,“18”為“i”和“n”之間單詞的個數,而“n”代表這個單詞的最后一個字母。在計算機領域,國際化是指設計能夠適應各種區域和語言環境的軟件的過程。
jQuery.i18n.properties 是一款輕量級的 jQuery 國際化插件。與 Java 里的資源文件類似,jQuery.i18n.properties 采用 .properties 文件對 JavaScript 進行國際化。jQuery.i18n.properties 插件根據用戶指定的(或瀏覽器提供的 )語言和國家編碼(符合 ISO-639 和 ISO-3166 標准)來解析對應的以“.properties”為后綴的資源文件。
利用資源文件實現國際化是一種比較流行的方式,例如 Android 應用就可以采用以語言和國家編碼命名的資源文件來實現國際化。jQuery.i18n.properties 插件中的資源文件以“.properties”為后綴,包含了區域相關的鍵值對。我們知道,Java 程序也可以使用以 .properties 為后綴的資源文件來實現國際化,因此,當我們要在 Java 程序和前端 JavaScript 程序中共享資源文件時,這種方式就顯得特別有用。jQuery.i18n.properties 插件首先加載默認的資源文件(例如:strings.properties),然后加載針對特定語言環境的資源文件(例如:strings_zh.properties),這就保證了在未提供某種語言的翻譯時,默認值始終有效。開發人員可以以 JavaScript 變量(或函數)或 Map 的方式使用資源文件中的 key。
總的來說,jQuery.i18n.properties 有一下一些特點:
- 使用 Java 標准的 .properties 文件作為資源文件,資源文件命名有以下三種格式:
123
basename_properties
basename_language.properties
basename_language_country.properties
- 使用 ISO-639 作為語言編碼標准,ISO-3166 作為國家名稱編碼標准
- 按順序加載默認資源文件和指定語言環境的資源文件,保證默認值始終可用
- 未指定語言環境時使用瀏覽器提供的語言
- 可以在資源字符串中使用占位符(例如:hello= 你好 {0}! 今天是 {1}。)
- 資源文件中的 Key 支持命名空間(例如:com.company.msgs.hello = Hello!)
- 支持跨行的值
- 可以以 JavaScript 變量(或函數)或 Map 的方式使用資源文件中的 Key
jQuery.i18n.properties API
jQuery.i18n.properties 的 API 非常簡單,只有少數幾個 API,即 jQuery.i18n.properties()、jQuery.i18n.prop()、jQuery.i18n.browserLang()。當然,和其他 jQuery 插件一樣,我們也可以采用 $.i18n.properties()、$.i18n.prop() 和 $.i18n.browserLang() 的形式使用這用這些 API。
jQuery.i18n.properties(settings)
該方法加載資源文件,其中 settings 是配置加載選項的一系列鍵值對,各配置項的具體描述如表 1 所示。
表 1. settings
jQuery.i18n.properties() 的使用方法如清單 1 所示。
清單 1. jQuery.i18n.properties() 用法
1
2
3
4
5
6
7
8
9
10
|
jQuery.i18n.properties({
name:'strings',// 資源文件名稱
path:'bundle/',// 資源文件所在目錄路徑
mode:'both',// 模式:變量或 Map
language:'pt_PT',// 對應的語言
cache:false,
encoding: 'UTF-8',
callback: function() {// 回調方法
}
});
|
jQuery.i18n.prop(key)
該方法以 map 的方式使用資源文件中的值,其中 key 指的是資源文件中的 key。當 key 指定的值含有占位符時,可以使用 jQuery.i18n.prop(key,var1,var2 … ) 的形式,其中 var1,var2 …對各占位符依次進行替換。例如資源文件中有“msg_hello= 您好 {0},今天是 {1}。”的鍵值對,則我們可以采用“jQuery.i18n.prop( ‘ msg_hello ’ , ’小明’ , ’星期一’ );”的形式使用 msg_hello。
jQuery.i18n.browserLang() 用於獲取瀏覽瀏覽器的語言信息,這里不再單獨介紹。
示例
下面我們以一個具體的示例來介紹如何通過 jQuery.i18n.properties 插件來實現 Web 前端的國際化。我們建立一個名為 hello-i18n 的 Java Web 應用,該應用根據瀏覽器的語言決定以英文或中文顯示登錄界面,登錄成功后以相應的語言顯示歡迎信息,登錄失敗則以相應的語言顯示錯誤信息。
為了達到松耦合的目的,前端采用純 JavaScript+HTML 來實現(我們的目的是介紹如何實現國際化,而不是如何美化界面,因此暫不使用 CSS),服務器端采用 RESTFul Web 服務。前端通過 jQuery Ajax 的方式與服務器端進行交互,避免 JSP 等傳統 Java Web 應用中前后端代碼冗雜在一起的現象。
開發測試環境
- 操作系統:Windows7 64 位專業版。
- IDE:Eclipse-JEE-Juno。
- Libs:jQuery 1.7.1,jQuery.i18n.properties 1.0.9,Apache Wink 1.1.3。
- 測試瀏覽器:Google Chrome 21.0.1180.83 m,FireFox 15.0.1。
服務器端的 RESTFul Web 服務
我們采用 Apache Wink 來實現服務器端 RESTFul Web 服務(關於如何使用 Apache Wink 來實現 RESTFul Web 服務,請參考“參考資料”一節中關於 Wink 的參考資料),這個 Web 服務實現用戶驗證功能。由於我們的重點不在服務器端,因此我們不真正驗證用戶,而是模擬驗證功能,並生成一個假的密鑰(在真實的環境中,密鑰會被用來對其他 REST 請求進行驗證)。REST API 如表 2 所示,代碼如清單 2 所示。
表 2. REST API
清單 2. REST 代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@Path("/users")
public class RESTApi {
@Path("/{id}/tokens")
@POST
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
public Response authenticate(@PathParam("id") String id,
Map<
String
, Object> payload) {
// 模擬驗證功能,僅當用戶名為"i18n", 密碼為"123456"時驗證成功
if (id.equals("i18n")) {
String pwd = (String) payload.get("password");
if (pwd.equals("123456")) {
// 生成模擬密鑰
Map<
String
, String> token = new HashMap<
String
, String>();
token.put("token",
"Y29udHJvbGxlci5yZWFkIiwib3BlbmlkIiwicGFzc3dvcmQud3JpdGUiXSwiZW...");
return Response.status(Status.OK).entity(token).build();
} else {
return Response.status(Status.UNAUTHORIZED).build();
}
}
return Response.status(Status.FORBIDDEN).build();
}
}
|
建立資源文件
在 Eclipse 中,對 hello-i18n 項目建立如圖 1 所示的目錄結構。
圖 1. 項目組織結構
在 i18n 目錄下創建 strings.properties 和,stirngs_zh.properties 兩個資源文件,其中 strings.properties 對應默認翻譯,如清單 3 所示;string_zh.properties 對應中文翻譯,如清單 4 所示。
清單 3. stirngs.properties
1
2
3
4
5
6
|
string_username=User name
string_password=Password
string_login=Login
string_hello=Hello {0},Welcome to jQuery.i18n.properties,your token is {1}。
string_usernotexist=User does not exist
string_wrongpassword=Wrong Password
|
清單 4. strings_zh.properties
1
2
3
4
5
6
|
string_username= 用戶名
string_password= 密碼
string_login= 登陸
string_hello= 您好 {0},歡迎使用 jQuery.i18n.properties,您的密鑰是:{1}。
string_usernotexist= 用戶不存在
string_wrongpassword= 密碼錯誤
|
引用 jQuery.i18n.properties 插件
和其他 jQuery 插件一樣,jQuery.i18n.properties 插件依賴於 jQuery,因此我們首先需要引用 jQuery。jQuery.i18n.properties 對 jQuery 的版本沒有明確要求,這里我們使用 jQuery-1.7.1。我們使用清單 5 所示的方式在 index.html 中引用 jQuery 和 jQuery.i18n.properties 插件。
清單 5. 引用 jQuery.i18n.properties
1
2
3
4
|
<script type="text/javascript" src="resources/lib/jquery-1.7.1.min.js">
</script>
<script type="text/javascript" src="resources/lib/jquery.i18n.properties-1.0.9.js">
</script>
|
index .html 中還定義了界面元素,如清單 6 所示。
清單 6. 界面元素
1
2
3
4
5
6
7
8
9
10
11
|
<
div
id
=
"content"
>
<
div
>
<
label
id
=
"label_username"
></
label
>
<
input
type
=
"text"
id
=
"username"
></
input
>
</
div
>
<
div
>
<
label
id
=
"label_password"
></
label
>
<
input
type
=
"password"
id
=
"password"
></
input
>
</
div
>
<
input
type
=
"button"
id
=
"button_login"
/>
</
div
>
|
使用 jQuery.i18n.properties 插件
在 main.js,使用清單 7 所示的方法加載資源文件,清單 7 中未指定“language”參數選項,表示使用瀏覽器語言。除了在 jQuery.i18n.properties() 定義的回調函數中使用資源文件中的定義的值外,成功加載資源文件后,我們也可以在其它地方使用這些值。
清單 7. 加載資源文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function loadProperties(){
jQuery.i18n.properties({// 加載資瀏覽器語言對應的資源文件
name:'strings', // 資源文件名稱
path:'resources/i18n/', // 資源文件路徑
mode:'map', // 用 Map 的方式使用資源文件中的值
callback: function() {// 加載成功后設置顯示內容
// 顯示“用戶名”
$('#label_username').html($.i18n.prop('string_username'));
// 顯示“密碼”
$('#label_password').html($.i18n.prop('string_password'));
// 顯示“登錄”
$('#button_login').val($.i18n.prop('string_login'));
}
});
}
|
當用戶點擊登錄按鈕后,我們使用 REST 請求將用戶信息發送到前文定義的 RESTFul Web 服務,若用戶信息驗證成功,則顯示歡迎信息和 Web 服務返回的密鑰,若驗證失敗則顯示錯誤信息,代碼如清單 8 所示。
清單 8. 前端登錄邏輯
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
$('#button_login').click(function(){// 點擊登錄按鈕后驗證用戶信息
var id = $('#username').val();// 用戶名
var payload = {};
payload['password']=$('#password').val();
payload = $.toJSON(payload);
$.ajax({
url : 'rest/users/' + id + '/tokens',//REST URI
type : 'POST',
data: payload, // Request body
contentType : 'application/json',
dataType:'json',
success : function(data) {
// 驗證成功則顯示歡迎信息和密鑰
// 使用含占位符的值
$('#content').html($.i18n.prop('string_hello',id,data.token));
},
error : function(jqXHR, textStatus, errorThrown) {
if(jqXHR.status == 403){
// 用戶不存在
alert($.i18n.prop('string_usernotexist'));
}else if(jqXHR.status == 401){
// 密碼錯誤
alert($.i18n.prop('string_wrongpassword'));
}else{
// 其他異常信息
alert(errorThrown);
}
}
});
});
|
運行效果
將 hello-i18n 項目部署到本地的 Tomcat 上,打開 Chrome 瀏覽器,將語言設置為英文,在地址欄中輸入 http://localhost:8080/hello-i18n,運行效果如圖 2 所示。
圖 2. 英文環境下的運行效果
將語言更改為簡體中文,重啟 Chrome,運行效果如圖 3 所示。
圖 3. 中文環境下的運行效果
問題與改進
資源文件命名問題
在上面的示例中,我們的程序只自動識別中文和英文兩種翻譯,而不能進一步區分簡體中文與繁體中文。為了使上面的示例能夠根據瀏覽器語言設置自動區分簡體中文和繁體中文,我們將簡體中文對應的資源文件 strings_zh.properties 重命名為 strings_zh_CN.properties,並添加如清單 9 所示的繁體中文資源文件 strings_zh_TW.properties。
清單 9. strings_zh_TW.properties
1
2
3
4
5
6
|
string_username= 用戶名
string_password= 密碼
string_login= 登入
string_hello= 您好 {0},歡迎使用 jQuery.i18n.properties,您的密鑰是:{1}。
string_usernotexist= 用戶不存在
string_wrongpassword= 密碼錯誤
|
運行程序,分別將瀏覽器語言設置為“中文(簡體中文)”和“中文(繁體中文)”進行測試,發現程序並不能如我們預期顯示簡體中文和繁體中文,而是都以英文顯示。分析后發現,造成這種現象的原因,是 jQuery.i18n.properties 插件默認的資源文件命名方式與瀏覽器上報的語言區域編碼不一致,從而導致插件加載資源文件失敗。以簡體中文為例,jQuery.i18n.properties 默認的資源文件命名方式為“zh_CN”的形式,而瀏覽器上報的語言區域編碼為 zh-CN”的形式,此時 jQuery.i18n.properties 插件加載資源文件的步驟如下:
- 加載默認資源文件即 strings.properties,成功。
- 加載名稱為 strings_zh.properties 的資源文件,失敗。
- 加載名稱為 stirngs_zh-CN.properties 的資源文件,失敗。
由於第 2 步和第 3 步都失敗,所以 jQuery.i18n.properties 使用默認資源文件 strings.properties 中的翻譯,也就是英文翻譯。同理,繁體中文也不能正常顯示。解決該問題有 3 種方法:
- 采用 strings_zh-CN.properties 的方式命名資源文件。這是最簡單的方法,但這種命名方式和 Java 標准的資源文件命名方式不一致;
- 使用默認的資源文件命名方式,並在調用 jQuery.i18n.properties() 方法之前使用 var lang = jQuery.i18n.browserLang()
的方式
顯式獲取瀏覽器的語言,然后將 lang 中的“-”替換為”_”,並在使用 jQuery.i18n.properties() 方法時將 lang 作為參數。 - 更改 jQuery.i18n.properties 的源碼。
這里我們采用最簡單的第一種方式,將簡體中文對應的資源文件 string_zh_CN.properties 重命名為 stirngs_zh-CN.properties,並將繁體中文對應的資源文件 strings_zh_TW.properties 重命名為 strings_zh-TW.properties。現在,程序就可以根據瀏覽器語言設置自動區分簡體中文和繁體中文了,繁體中文的運行效果如圖 4 所示。
圖 4. 繁體中文環境下的運行效果
總結
本文對 jQuery 國際化插件 jQuery.i18n.properties 進行了介紹,並用實際例子介紹了如何使用 jQuery.i18n.properties 插件實現 Web 前端的國際化。總結起來,jQuery.i18n.properties 具有輕量級(壓縮后僅 4kb)、簡單易用等特點,但是作為一個普及度不高的輕量級插件,不一定適用於大型的或對效率要求極高的場景。
希望本文能為正在尋找小型 Web 應用前端國際化解決方案的讀者提供一定的參考。