Files
build-web-application-with-…/zh-tw/10.3.md
2019-06-22 23:41:28 +08:00

215 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- {% raw %} -->
# 10.3 國際化站點
前面小節介紹了如何處理本地化資源,即 Locale 一個相應的配置檔案,那麼如果處理多個的本地化資源呢?而對於一些我們經常用到的例如:簡單的文字翻譯、時間日期、數字等如果處理呢?本小節將一一解決這些問題。
## 管理多個本地包
在開發一個應用的時候首先我們要決定是隻支援一種語言還是多種語言如果要支援多種語言我們則需要制定一個組織結構以方便將來更多語言的新增。在此我們設計如下Locale 有關的檔案放置在 config/locales 下,假設你要支援中文和英文,那麼你需要在這個資料夾下放置 en.json 和 zh.json。大概的內容如下所示
```json
# zh.json
{
"zh": {
"submit": "提交",
"create": "建立"
}
}
# en.json
{
"en": {
"submit": "Submit",
"create": "Create"
}
}
```
為了支援國際化,在此我們使用了一個國際化相關的套件——[go-i18n](https://github.com/astaxie/go-i18n),首先我們向 go-i18n 套件註冊 config/locales 這個目錄,以載入所有的 locale 檔案
```Go
Tr:=i18n.NewLocale()
Tr.LoadPath("config/locales")
```
這個套件使用起來很簡單,你可以透過下面的方式進行測試:
```Go
fmt.Println(Tr.Translate("submit"))
//輸出 Submit
Tr.SetLocale("zh")
fmt.Println(Tr.Translate("submit"))
//輸出“提交”
```
## 自動載入本地套件
上面我們介紹了如何自動載入自訂語言套件,其實 go-i18n 函式庫已經預載入了很多預設的格式資訊,例如時間格式、貨幣格式,使用者可以在自訂配置時改寫這些預設配置,請看下面的處理過程:
```Go
//載入預設配置檔案,這些檔案都放在 go-i18n/locales 下面
//檔案命名 zh.json、en.json、en-US.json 等,可以不斷的擴充套件支援更多的語言
func (il *IL) loadDefaultTranslations(dirPath string) error {
dir, err := os.Open(dirPath)
if err != nil {
return err
}
defer dir.Close()
names, err := dir.Readdirnames(-1)
if err != nil {
return err
}
for _, name := range names {
fullPath := path.Join(dirPath, name)
fi, err := os.Stat(fullPath)
if err != nil {
return err
}
if fi.IsDir() {
if err := il.loadTranslations(fullPath); err != nil {
return err
}
} else if locale := il.matchingLocaleFromFileName(name); locale != "" {
file, err := os.Open(fullPath)
if err != nil {
return err
}
defer file.Close()
if err := il.loadTranslation(file, locale); err != nil {
return err
}
}
}
return nil
}
```
透過上面的方法載入配置資訊到預設的檔案,這樣我們就可以在我們沒有自訂時間資訊的時候執行如下的程式碼取得對應的資訊:
```Go
//locale=zh 的情況下,執行如下程式碼:
fmt.Println(Tr.Time(time.Now()))
//輸出2009 年 1 月 08 日 星期四 20:37:58 CST
fmt.Println(Tr.Time(time.Now(),"long"))
//輸出2009 年 1 月 08 日
fmt.Println(Tr.Money(11.11))
//輸出:¥11.11
```
## template mapfunc
上面我們實現了多個語言套件的管理和載入,而一些函式的實現是基於邏輯層的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等雖然我們在邏輯層可以利用這些函式把需要的參數進行轉換後在範本層渲染的時候直接輸出但是如果我們想在模版層直接使用這些函式該怎麼實現呢不知你是否還記得在前面介紹範本的時候說過Go 語言的範本支援自訂範本函式,下面是我們實現的方便操作的 mapfunc
1. 文字資訊
文字資訊呼叫`Tr.Translate`來實現相應的資訊轉換mapFunc 的實現如下:
```Go
func I18nT(args ...interface{}) string {
ok := false
var s string
if len(args) == 1 {
s, ok = args[0].(string)
}
if !ok {
s = fmt.Sprint(args...)
}
return Tr.Translate(s)
}
```
註冊函式如下:
```Go
t.Funcs(template.FuncMap{"T": I18nT})
```
範本中使用如下:
```Go
{{.V.Submit | T}}
```
2. 時間日期
時間日期呼叫`Tr.Time`函式來實現相應的時間轉換mapFunc 的實現如下:
```Go
func I18nTimeDate(args ...interface{}) string {
ok := false
var s string
if len(args) == 1 {
s, ok = args[0].(string)
}
if !ok {
s = fmt.Sprint(args...)
}
return Tr.Time(s)
}
```
註冊函式如下:
```Go
t.Funcs(template.FuncMap{"TD": I18nTimeDate})
```
範本中使用如下:
```Go
{{.V.Now | TD}}
```
3. 貨幣資訊
貨幣呼叫`Tr.Money`函式來實現相應的時間轉換mapFunc 的實現如下:
```Go
func I18nMoney(args ...interface{}) string {
ok := false
var s string
if len(args) == 1 {
s, ok = args[0].(string)
}
if !ok {
s = fmt.Sprint(args...)
}
return Tr.Money(s)
}
```
註冊函式如下:
```Go
t.Funcs(template.FuncMap{"M": I18nMoney})
```
範本中使用如下:
```Go
{{.V.Money | M}}
```
## 總結
透過這小節我們知道了如何實現一個多語言套件的 Web 應用透過自訂語言套件我們可以方便的實現多語言而且透過配置檔案能夠非常方便的擴充多語言預設情況下go-i18n 會自定載入一些公共的配置資訊,例如時間、貨幣等,我們就可以非常方便的使用,同時為了支援在範本中使用這些函式,也實現了相應的範本函式,這樣就允許我們在開發 Web 應用的時候直接在範本中透過 pipeline 的方式來操作多語言套件。
## links
* [目錄](<preface.md>)
* 上一節:[本地化資源](<10.2.md>)
* 下一節:[小結](<10.4.md>)
<!-- {% endraw %} -->