Go Revel - i18n(國際化)
##Messages
`Messages`信息是對內容提供翻譯的外部文本片段。revel提供了組織每一種語言文本片段的message文件、自動區域查找、基于cookie覆蓋的消息嵌套和參數。
術語表:
Locale: 語言和區域的組合,表示一個用戶首選語言, 例如 en-US
Language: 一個區域的語言部分, 例如 en. 預期為 ISO 639-1 編碼
Region: 地區, 例如. US. 地區預期為 ISO 3166-1 alpha-2 編碼
##示例程序
revel處理message文件和國際化和其他的web框架差不多,在`revel/samples/i18n`示例中可以了解詳盡的使用方法。
##Message文件
`Messages`被定義在message文件,這些文件的message文本將被用于渲染模板(或程序中其他所期望的地方)。
創建一個新的meesage文件,需要記住一下幾點:
1、所有message文件應當存儲在程序根目錄下的`meesages`目錄中
2、文件擴展名必須是當前語言的 ISO 639-1 編碼
3、message文件應當是`UTF-8`編碼. 雖然這不是強制要求,但這是最佳實踐
4、沒一個message文件實際上是`goconfig`格式的文件,它支持`goconfig`的所有功能
##組織Message文件
Message文件對名稱沒有任何限制,只要具有有效的擴展名。每一種語言也沒有限定Message文件的數量。在程序啟動時,revel會解析`messages`目錄中所有的文件,并按它們的語言分別合并到一起。這意味著可以按自己想要的方式來組織message文件。
例如,按傳統的方式每一種語言定義單獨的message文件:
/app
/messages
messages.en
messages.fr
...
或者另一種方法,同一種語言按類型創建多個不同的message文件:
/app
/messages
labels.en
warnings.en
labels.fr
warnings.fr
...
注意,在同一語言中定義相同鍵的多個message,這樣雖然在技術上是可行的,但會帶來不可預知的行為。在同一種語言使用多個message文件時,注意保持鍵的唯一,免得被后面同名key的值覆蓋。
##Message鍵值對
message文件本質上是一個`goconfig`文件,這意味著它必須嚴格的遵守鍵值對格式:
key=value
例如:
greeting=Hello
greeting.name=Rob
greeting.suffix=, welcome to Revel!
##分段
一個 `goconfig`文件可以備份為若干段,默認段總是存在并包含沒有被定義進任何分段的鍵值對。例如:
key=value
[SECTION]
key2=value2
Message文件的所有message應被定義進默認分段,除非他們屬于這個語言的某個特定`Region`地區。
##地區
特定區域的message應以相同的名稱定義在不同的分段中。假如,要對所有英語用戶說"你好",英國用戶應為"Hey",美國用戶應為"Howdy",為了做到這點,我們定義如下message文件:
greeting=Hello
[GB]
greeting=Hey
[US]
greeting=Howdy
如果用戶已經定義了自己的首選語言,revel會自動的使用相應語言來“問好”。
只有在特定情況下,用戶的區域被明確定義為`en-GB`或`en-US`,問候消息才會使用特定的message解決。
如果一個Meesage定義在一個無效的分段里,雖然技術上可行,但是它們永遠不會被使用。
##引用和參數
**引用**
Meesage文件中的message,可以引用其他message。這使得用戶可以從一個或多個Message組成一個單一的message。引用其他message的語法為`%(key)s`。例如:
greeting=Hello
greeting.name=Rob
greeting.suffix=, welcome to Revel!
greeting.full=%(greeting)s %(greeting.name)s%(greeting.suffix)s
注:goconfig文件支持引用,由于message文件支持合并,所以可以從其他相同語言的message文件進行引用。
**參數**
Message支持一個或多個參數。參數使用go `fmt`包中同樣的規則解析。例如:
greeting.name_arg=Hello %s!
參數按照給定的順序來解析。
##解析客戶端語言環境
為了弄清楚客戶端的首選語言,revel會在以下地方尋找:
1、語言cookie
revel會在沒一個請求的cookie中尋找程序配置的i18n字段(`i18n.cookie`),如果找到,那么這個字段的值就被認為是客戶端當前的語言環境。
2、`Accept-Language`請求頭
revel會自動解析每個請求頭中的`Accept-Language`, 每個`Accept-Language`都會被保存在`Request`實例中,用于在以后的各種message函數中確定當前語言環境。
3、默認語言
當上面所有的方法都沒有正確查找到客戶端的語言環境時,revel會將程序配置文件中定義的`i18n.default_language`值作為默認語言。
當請求的message無法得到時,會返回一個包含原始信息的特定字符串。
注:每次請求的`Accept-Language`請求頭都會被解析并存儲在`Request`實例中,即使cookie中已經定義了語言。在這種情況下,它的值雖然不會被message解析函數使用,但我們仍然可以在程序中使用它。
**獲取當前的語言環境**
程序可以通過`Request.Locale`從當前的請求中獲取被設置的語言環境。
例如:
func (c App) Index() revel.Result {
currentLocale := c.Request.Locale
c.Render(currentLocale)
}
在模板中,可以從傳入的`renderArgs`對象獲取當前語言環境:
Current preferred locale: {{.currentLocale}}
##解析`Accept-Language`HTTP頭 如果程序要訪問`Accept-Language`HTTP請求頭,可以通過controller的`Request`實例來獲得。`AcceptLanguages`是一個`AcceptLanguage`的切片對象,包含了從相應的頭字段中解析出來的值,按其含義的標識價值來排序。 func (c App) Index() revel.Result { // 獲得 AcceptLanguages的字符串表示 c.RenderArgs["acceptLanguageHeaderParsed"] = c.Request.AcceptLanguages.String() // 獲得最有價值的 AcceptLanguage 實例 c.RenderArgs["acceptLanguageHeaderMostQualified"] = c.Request.AcceptLanguages[0] c.Render() } ##解析Message Message可以從任意一個controller或view視圖模板解析。 **Controller** 任何控制器都有`Message(message string, args ...interface{})`方法來講message解析為當前語言。如: func (c App) Index() revel.Result { c.RenderArgs["controllerGreeting"] = c.Message("greeting") c.Render() } **模板** 在模板中,可以使用模板函數`msg`來講message解析為當前語言:Greetings without arguments: {{msg . "greeting"}}
Greetings: {{msg . "greeting.full.name" "Tommy Lee Jones"}}
注:模板函數`msg`的簽名為 `msg . "message name" "argument" "argument"`,如果沒有參數,則不會解析任何message。 ##配置 文件 屬性 描述 app.conf i18n.cookie cookie中語言字段的名稱. 應當加上revel前綴避免沖突. app.conf i18n.default_language 在沒有任何首選語言的情況下所使用的默認語言.
浙公網安備 33010602011771號