149 lines
6.0 KiB
Markdown
149 lines
6.0 KiB
Markdown
<!-- {% raw %} -->
|
||
# 10.2 本地化資源
|
||
前面小節我們介紹瞭如何設定Locale,設定好Locale之後我們需要解決的問題就是如何儲存相應的Locale對應的資訊呢?這裡面的資訊包括:文字資訊、時間和日期、貨幣值、圖片、包含檔案以及檢視等資源。那麼接下來我們將對這些資訊一一進行介紹,Go語言中我們把這些格式資訊儲存在JSON中,然後透過合適的方式展現出來。(接下來以中文和英文兩種語言對比舉例,儲存格式檔案en.json和zh-CN.json)
|
||
## 本地化文字訊息
|
||
文字資訊是編寫Web應用中最常用到的,也是本地化資源中最多的資訊,想要以適合本地語言的方式來顯示文字資訊,可行的一種方案是:建立需要的語言相應的map來維護一個key-value的關係,在輸出之前按需從適合的map中去取得相應的文字,如下是一個簡單的示例:
|
||
|
||
```Go
|
||
|
||
package main
|
||
|
||
import "fmt"
|
||
|
||
var locales map[string]map[string]string
|
||
|
||
func main() {
|
||
locales = make(map[string]map[string]string, 2)
|
||
en := make(map[string]string, 10)
|
||
en["pea"] = "pea"
|
||
en["bean"] = "bean"
|
||
locales["en"] = en
|
||
cn := make(map[string]string, 10)
|
||
cn["pea"] = "豌豆"
|
||
cn["bean"] = "毛豆"
|
||
locales["zh-CN"] = cn
|
||
lang := "zh-CN"
|
||
fmt.Println(msg(lang, "pea"))
|
||
fmt.Println(msg(lang, "bean"))
|
||
}
|
||
|
||
func msg(locale, key string) string {
|
||
if v, ok := locales[locale]; ok {
|
||
if v2, ok := v[key]; ok {
|
||
return v2
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
```
|
||
上面示例示範了不同locale的文字翻譯,實現了中文和英文對於同一個key顯示不同語言的實現,上面實現了中文的文字訊息,如果想切換到英文版本,只需要把lang設定為en即可。
|
||
|
||
有些時候僅是key-value替換是不能滿足需要的,例如"I am 30 years old",中文表達是"我今年30歲了",而此處的30是一個變數,該怎麼辦呢?這個時候,我們可以結合`fmt.Printf`函式來實現,請看下面的程式碼:
|
||
```Go
|
||
|
||
en["how old"] ="I am %d years old"
|
||
cn["how old"] ="我今年%d歲了"
|
||
|
||
fmt.Printf(msg(lang, "how old"), 30)
|
||
```
|
||
上面的示例程式碼僅用以示範內部的實現方案,而實際資料是儲存在JSON裡面的,所以我們可以透過`json.Unmarshal`來為相應的map填充資料。
|
||
|
||
## 本地化日期和時間
|
||
因為時區的關係,同一時刻,在不同的地區,表示是不一樣的,而且因為Locale的關係,時間格式也不盡相同,例如中文環境下可能顯示:`2012年10月24日 星期三 23時11分13秒 CST`,而在英文環境下可能顯示:`Wed Oct 24 23:11:13 CST 2012`。這裡面我們需要解決兩點:
|
||
|
||
1. 時區問題
|
||
2. 格式問題
|
||
|
||
$GOROOT/lib/time套件中的timeinfo.zip含有locale對應的時區的定義,為了獲得對應於當前locale的時間,我們應首先使用`time.LoadLocation(name string)`取得相應於地區的locale,比如`Asia/Shanghai`或`America/Chicago`對應的時區資訊,然後再利用此資訊與呼叫`time.Now`獲得的Time物件協作來獲得最終的時間。詳細的請看下面的例子(該例子採用上面例子的一些變數):
|
||
|
||
```Go
|
||
|
||
en["time_zone"]="America/Chicago"
|
||
cn["time_zone"]="Asia/Shanghai"
|
||
|
||
loc,_:=time.LoadLocation(msg(lang,"time_zone"))
|
||
t:=time.Now()
|
||
t = t.In(loc)
|
||
fmt.Println(t.Format(time.RFC3339))
|
||
|
||
```
|
||
我們可以透過類似處理文字格式的方式來解決時間格式的問題,舉例如下:
|
||
```Go
|
||
|
||
en["date_format"]="%Y-%m-%d %H:%M:%S"
|
||
cn["date_format"]="%Y年%m月%d日 %H時%M分%S秒"
|
||
|
||
fmt.Println(date(msg(lang,"date_format"),t))
|
||
|
||
func date(fomate string,t time.Time) string{
|
||
year, month, day = t.Date()
|
||
hour, min, sec = t.Clock()
|
||
//解析相應的%Y %m %d %H %M %S然後返回資訊
|
||
//%Y 替換成2012
|
||
//%m 替換成10
|
||
//%d 替換成24
|
||
}
|
||
|
||
```
|
||
## 本地化貨幣值
|
||
各個地區的貨幣表示也不一樣,處理方式也與日期差不多,細節請看下面程式碼:
|
||
```Go
|
||
|
||
en["money"] ="USD %d"
|
||
cn["money"] ="¥%d元"
|
||
|
||
fmt.Println(money_format(msg(lang,"date_format"),100))
|
||
|
||
func money_format(fomate string,money int64) string{
|
||
return fmt.Sprintf(fomate,money)
|
||
}
|
||
|
||
```
|
||
## 本地化檢視和資源
|
||
我們可能會根據Locale的不同來展示檢視,這些檢視包含不同的圖片、css、js等各種靜態資源。那麼應如何來處理這些資訊呢?首先我們應按locale來組織檔案資訊,請看下面的檔案目錄安排:
|
||
```html
|
||
|
||
views
|
||
|--en //英文範本
|
||
|--images //儲存圖片資訊
|
||
|--js //儲存JS檔案
|
||
|--css //儲存css檔案
|
||
index.tpl //使用者首頁
|
||
login.tpl //登陸首頁
|
||
|--zh-CN //中文範本
|
||
|--images
|
||
|--js
|
||
|--css
|
||
index.tpl
|
||
login.tpl
|
||
|
||
```
|
||
有了這個目錄結構後我們就可以在渲染的地方這樣來實現程式碼:
|
||
```Go
|
||
|
||
s1, _ := template.ParseFiles("views/"+lang+"/index.tpl")
|
||
VV.Lang=lang
|
||
s1.Execute(os.Stdout, VV)
|
||
```
|
||
而對於裡面的index.tpl裡面的資源設定如下:
|
||
```html
|
||
|
||
// js檔案
|
||
<script type="text/javascript" src="views/{{.Lang}}/js/jquery/jquery-1.8.0.min.js"></script>
|
||
// css檔案
|
||
<link href="views/{{.Lang}}/css/bootstrap-responsive.min.css" rel="stylesheet">
|
||
// 圖片檔案
|
||
<img src="views/{{.Lang}}/images/btn.png">
|
||
```
|
||
採用這種方式來本地化檢視以及資源時,我們就可以很容易的進行擴充套件了。
|
||
|
||
## 總結
|
||
本小節介紹瞭如何使用及儲存本地資源,有時需要透過轉換函式來實現,有時透過lang來設定,但是最終都是透過key-value的方式來儲存Locale對應的資料,在需要時取出相應於Locale的資訊後,如果是文字資訊就直接輸出,如果是時間日期或者貨幣,則需要先透過`fmt.Printf`或其他格式化函式來處理,而對於不同Locale的檢視和資源則是最簡單的,只要在路徑裡面增加lang就可以實現了。
|
||
|
||
## links
|
||
* [目錄](<preface.md>)
|
||
* 上一節: [設定預設地區](<10.1.md>)
|
||
* 下一節: [國際化站點](<10.3.md>)
|
||
<!-- {% endraw %} -->
|