# 国际化 (i18n)
## 目录
1. [如何支持多种语言](#l10)
2. [预定义的message](#overview-predefined)
3. [语言环境](#overview-locales)
1. [已支持的语言环境](#locales-supported)
2. [扩展怎么找到字符串](#locales-usage)
3. [如何设置浏览器语言](#locales-testing)
4. [示例](#overview-examples)
1. [例: getMessage](#examples-getMessage)
2. [例: getAcceptLanguages](#example-accept-languages)
5. [API 介绍: chrome.i18n](#apiReference)
国际化 (i18n)
一个支持国际化的扩展能很容易被本地化,但原始不支持自动确认语言和地区。
为了国际化您的扩展,您需要把所有用户可见字符串保存在文件名为messages.json的文件里。每当你本地化您的扩展时,您需要在_locales/localeCode下增加这个messages.json文件,lo_caleCode_ 是一个形如en代表英语的编码。
下面是一个支持英语(en)、西班牙语(es)和韩语(ko)的国际化扩展文件层次结构图。
![In the extension directory: manifest.json, *.html, *.js, _locales directory. In the _locales directory: en, es, and ko directories, each with a messages.json file.](https://box.kancloud.cn/2015-12-28_5680ab14d1888.gif)
## 如何支持多种语言
假设您有一个如下图所列文件的扩展:
![A manifest.json file and a file with JavaScript. The .json file has 'name': 'Hello World'. The JavaScript file has title = 'Hello World';](https://box.kancloud.cn/2015-12-28_5680ab14dfa42.gif)
为了国际化这个扩展,您需要先命名每个用户可见的字符串,然后将它们保存在messages.json文件里。这个扩展的manifest、CSS和JavaScript代码文件就能根据每个字符串的名字提取到他们的本地化版本。
下图是一个国际化扩展的文件规范示意图(它只支持英语字符串)
![In the manifest.json file, 'Hello World' has been changed to '__MSG_extName__', and a new 'default_locale' item has the value 'en'. In the JavaScript file, 'Hello World' has been changed to chrome.i18n.getMessage('extName'). A new file named _locales/en/messages.json defines 'extName'.](https://box.kancloud.cn/2015-12-28_5680ab14ed518.gif)
**重要提示:**如果一个扩展有_locales目录,那么manifest文件必须定义"default_locale"字段内容。
国际化扩展的一些方法、规则或技巧:
* 你能使用任何一种[被支持的 locales](#overview-locales). 如果您使用未支持的locale,Google Chrome会忽略它。
* 在manifest.json和CSS文件中,像下图一样引用一个字符串:
```
__MSG__messagename___
```
* 在您的扩展JavaScript程序中,像下图一样引用一个字符串:
```
chrome.i18n.getMessage("_messagename_")
```
* 每次调用getMessage(),最多能返回9个字符串。查看[Examples: getMessage](#examples-getMessage)连接了解更多信息
* 国际化系统已经提供了一些 message, 像 @@bidi_dir 和 @@ui_locale。 查看 [Predefined messages](#overview-predefined) 连接了解全部预定义message 名称。
* 在message.json文件里,每个用户可用的字符串都有一个名字项,一个"message"项和一个可选的"description"项。这个名字如"extName"或"search_string"是字符串的ID, "message"是字符串在当前语言环境中的值。"description"有一些解释信息。示例:
```
{
"search_string": {
"message": "hello%20world",
"description": "The string we search for. Put %20 between words that go together."
},
...
}
```
了解更多信息,请查看[Formats: Locale-Specific Messages](http://code.google.com/chrome/extensions/i18n-messages.html).
一旦国际化了扩展,就很容易支持其它语言了。1、拷贝一个message.json,翻译其字符串,然后将它保存在_locales目录下。例如:为了支持西班牙语,只要翻译好一个message.json,放在_locales/es目录下。下图展示了上述扩展在支持了西班牙语以后的文件层次图。
![This looks the same as the previous figure, but with a new file at _locales/es/messages.json that contains a Spanish translation of the messages.](https://box.kancloud.cn/2015-12-28_5680ab15084ef.gif)
## 预定义 messages
国际化系统提供一些预定义messages来帮助您本地化扩展。这些包括@@ui_locale(您能用它检测当前UI系统的语言信息),也包括一些以@@bidi_作前部的message(用来检测文字方向书写习惯,像英语的是从左到右书写习惯),它们(@@bidi_)有相似的名字, 例举于:[gadgets BIDI (bi-directional) API](i18n.html#BIDI).
@@extension_id message 能用在任意扩展 的CSS和JavaScript 文件中,无论其是否已经本地化,但不能用在manifest.json文件中。
**注意:**Content script CSS files 不能用一些预定义message,像 @@extension_id。更多信息参见[bug 39899](http://crbug.com/39899).
下表描述了每个预定义的message。
| Message 名字 | 描述 |
| --- | --- |
| @@extension_id | 这个扩展的 ID; 您可以在扩展内部用这个字符串构造URL用于访问某些资源。 没有本地化的扩展也可以使用这个message.
**注意:** 您不能在manifest文件中使用这个message |
| @@ui_locale | 当前语言; 您可以用这个字符串构造和语言环境相关的URL。 |
| @@bidi_dir | 当前语言环境的文字方向, 要么是 "ltr" (代表从左到向的语言,如英语)。要么是rtl" (代表右到左的语言,如日语)。 |
| @@bidi_reversed_dir | 其值是对@@bidi_dir取反。如果 @@bidi_dir 是 "ltr", 那么它是 "rtl", 否则它是 "ltr".。 |
| @@bidi_start_edge | 如果 @@bidi_dir 是 "ltr", 那么它是 "left", 否则它是 "right". |
| @@bidi_end_edge | 如果 @@bidi_dir 是 "ltr", 那么它是 "right";,否则它是 "left". |
一个在CSS文件中,用@@extension_id 构造一个URL的示例:
```
body {
**background-image:url('chrome-extension://__MSG_@@extension_id__/background.png');**
}
```
如果扩展的ID是abcdefghijklmnopqrstuvwxyzabcdef,那么上述代码中的粗线部份变成:
```
background-image:url('chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef/background.png');
```
一个在CSS文件中用@@bidi_* messages 的例子:
```
body {
**direction: __MSG_@@bidi_dir__;**
}
div#header {
margin-bottom: 1.05em;
overflow: hidden;
padding-bottom: 1.5em;
**padding-__MSG_@@bidi_start_edge__: 0;**
**padding-__MSG_@@bidi_end_edge__: 1.5em;**
position: relative;
}
```
从左到右的语言,如英语。粗线变成:
```
dir: ltr;
padding-left: 0;
padding-right: 1.5em;
```
## 语言环境
扩展能使用所有Google Chrome支持的语言,,附加几个有几种地区变化的语言(如en : en_GB代表英式英语, en_US代表美式英语)。
### 已支持的语言
你的扩展能使用下列的任一种语言:
am ar bg bn ca cs da de el en en_GB en_US es es_419 et fi fil fr gu he hi hr hu id it ja kn ko ltlv ml mr nl or pl pt pt_BR pt_PT ro ru sk sl sr sv sw ta te th tr uk vi zh zh_CN zh_TW
### 扩展怎么查找字符串
您不是必须为每个语言定义各个字符串。支持国际化的扩展自带自动搜索功能,只要默认语言的message.json文件中字义了这些字符串,无论是什么语言,您的扩展都能运行起来。下面介绍扩展系统怎么搜索message.json:
1. 在用户首选的存在的语言中搜索messages文件 。举个例子:如果Google Chrome的语言设置为英式英语(en_GB),系统会先查找_locales/en_GB/messages.json,如果这个文件和其message存在,系统停止搜索。
2. 如果用户首选的语言编码有一个带下划线的地区标识码。如:en_US。那么系统会再次搜索en(不带US)的message文件。果这个文件和message存在,系统停止搜索。
3. 搜索扩展默认语言的messages 文件。举例:默认语言是 "ES",那么,搜索 _locales/es/messages.json.。
下图中,"colores"的message有三种语言支持,"extName"有两种。美式英语用户始终会看到标签"Colors",英式英语用户会看到标签"Clours",他们会同时看到标签"Hello World"。因为默认语言是西班牙语,所以非英语用户会看到标签"Colores"和扩展名称"Hola mundo"。
![Four files: manifest.json and three messages.json files (for es, en, and en_GB). The es and en files show entries for messages named 'extName' and 'colores'; the en_GB file has just one entry (for 'colores').](https://box.kancloud.cn/2015-12-28_5680ab1517177.gif)
### 怎么设置浏览器的语言
为了测试翻译,您可能需要设置浏览器的语言.这部份介绍怎么在[Windows](#testing-win),[Mac OS X](#testing-mac), and [Linux](#testing-linux)上设置语言。
#### Windows
你可以在locale-specific快捷方式或Google Chrome UI上改变语言。用快捷方式建立更快,并且这种方法能同时使用多种语言。
##### 使用locale-specific快捷方式
创建和使用快捷方式,运行特定语言的Google Chrome:
1. 复制一个Google Chrome的桌面快捷方式。
2. 用语言编码命名新的快捷方式,如cn_chrome.lnk。
3. 选择快捷方式的连接属性,加入--lang和--user-data-dir参数。如:
```
_path_to_chrome.exe_ --lang=_locale_ --user-data-dir=c:_locale_profile_dir_
```
4. 双击新的快捷方式运行Chrome。
示例:用西班牙语创建此类快捷方式:
```
_path_to_chrome.exe_ --lang=es --user-data-dir=c:chrome-profile-es
```
示例:你可以创建任意多的快捷方式,,让你的多种语言测试变很容易。
```
_path_to_chrome.exe_ --lang=en --user-data-dir=c:chrome-profile-en
_path_to_chrome.exe_ --lang=en_GB --user-data-dir=c:chrome-profile-en_GB
_path_to_chrome.exe_ --lang=ko --user-data-dir=c:chrome-profile-ko
```
**注意:**不是必须指定--user-data-dir,但是正如您所见,加这个参数也很容易。并且每为个语言指定一个user-data-dir目录,可以让你在同一时间运行几种语言的浏览器。 不过有一个缺点,因为语言数据是不共享的,所以您需要安装多次扩展(需要为为每种语言安装一次)。呵呵,当然你不想使用这种语言也可以不安装。查看[Creating and Using Profiles](http://www.chromium.org/developers/creating-and-using-profiles)连接获得更多信息。
##### 使用 UI
怎么使用windows版本Google Chrome UI 改变语言
1. 设置按钮(扳手图标)->选项
2. 选择当前标签页
3. 将页面滚动到底
4. 点击"改变字符和语言设置"
5. 选择语言标签
6. 使用下拉列表设置Google Chrome语言
7. 重启Chrome
#### Mac OS X
在Mac上改变语言,您需要使用系统preferences
1. 从Apple menu上选择**System Preferences**
2. 在**Personal**部份,选择**International**
3. 选择你的语言和地域
4. 重启chrome
#### Linux
Linux上改变语言,先退出Google Chrome,再如下设置环境变量,重启即可:
```
LANGUAGE=es ./chrome
```
## 一些例子
您能轻松的在[examples/api/i18n](http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/i18n/)目录下找到国际化的例子。[xamples/extensions/news](http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/)目录下有更完整的例子。[samples](samples.html)有代码级的其它例子和帮助。
### 函数 getMessage示例
下面的代码介绍了怎么得到和显示一个本地化的字符串。用"string1"和"string2"替换message的两个占位符。
```
function getMessage() {
var message = chrome.i18n.getMessage("click_here", ["string1", "string2"]);
document.getElementById("languageSpan").innerHTML = message;
}
```
如何提供和使用一个字符串。
```
_// In JavaScript code_
status.innerText = chrome.i18n.getMessage("error", errorDetails);
_// In messages.json_
"error": {
"message": "Error: $details$",
"description": "Generic error template. Expects error parameter to be passed in.",
"placeholders": {
"details": {
"content": "$1",
"example": "Failed to fetch RSS feed."
}
}
}
```
[Locale-Specific Messages](http://code.google.com/chrome/extensions/i18n-messages.html) 了解更多占位符的信息。关于调用函数getMessage()的更多信息参见[API reference](#method-getMessage).
### 函数getAcceptLanguages示例
下例代码介绍了怎么取得所有可用的语言,把它们以","号连接成字符串并显示。
```
function getAcceptLanguages() {
chrome.i18n.getAcceptLanguages(function(languageList) {
var languages = languageList.join(",");
document.getElementById("languageSpan").innerHTML = languages;
})
}
```
调用函数getAcceptLanguages()的更多细节请参见[API reference](#method-getAcceptLanguages).
## API 介绍: chrome.i18n
### 方法
#### getAcceptLanguages
chrome.i18n.getAcceptLanguages(functioncallback)
取得所有的可用语言,这个和浏览器使用的语言不同, 用window.navigator.language.取得这浏览器使用的语言
#### 参数
callback_(function)_
#### callback function
这个回调参数应该是一个函数,类似于:
```
function(array of string languages) {...};
```
languages_(array of string )_
浏览器可接受的语言数组, 类似于 en-US,en,zh-CN
#### getMessage
string chrome.i18n.getMessage(string messageName, string or array of string substitutions)
用指定的message取得字符串。如果message不存在,此方法返回空串。如果调用格式错误,如_messageName_不是一个串或是_substitution_为空或大于9个元素。此函数返回"undefined"
#### 参数
messageName_(string)_
message名字, 在[messages.json](http://code.google.com/chrome/extensions/i18n-messages.html)文件中使用的名字
substitutions_(optionalstring or array of string)_
如果message需要这个参数,设定1到9个子串。
#### 返回
_(string)_
当前语言设置的Message
- 基础文档
- 综述
- 调试
- 格式:Manifest文件
- 模式匹配
- 改变浏览器外观
- Browser Actions
- Context Menus
- 桌面通知
- Omnibox
- Override替代页
- Page Actions
- 主题
- 与浏览器交互
- 书签
- Cookies
- chrome.devtools.* APIs
- Events
- chrome.history
- Management
- 标签
- 视窗
- 实现扩展
- 无障碍性(a11y)
- 背景页
- Content Scripts
- 跨域 XMLHttpRequest 请求
- 国际化 (i18n)
- 消息传递
- Optional Permissions
- NPAPI 插件
- 完成并发布应用
- 自动升级
- 托管
- 打包
- 规范和协议
- 应用设计规范
- 开发人员协议
- 免责声明