前面小節介紹了如何處理本地化資源,即Locale一個相應的配置文件,那么如果處理多個的本地化資源呢?而對于一些我們經常用到的例如:簡單的文本翻譯、時間日期、數字等如果處理呢?本小節將一一解決這些問題。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.3.md#管理多個本地包)管理多個本地包
在開發一個應用的時候,首先我們要決定是只支持一種語言,還是多種語言,如果要支持多種語言,我們則需要制定一個組織結構,以方便將來更多語言的添加。在此我們設計如下:Locale有關的文件放置在config/locales下,假設你要支持中文和英文,那么你需要在這個文件夾下放置en.json和zh.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文件
~~~
Tr:=i18n.NewLocale()
Tr.LoadPath("config/locales")
~~~
這個包使用起來很簡單,你可以通過下面的方式進行測試:
~~~
fmt.Println(Tr.Translate("submit"))
//輸出Submit
Tr.SetLocale("zn")
fmt.Println(Tr.Translate("submit"))
//輸出“遞交”
~~~
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.3.md#自動加載本地包)自動加載本地包
上面我們介紹了如何自動加載自定義語言包,其實go-i18n庫已經預加載了很多默認的格式信息,例如時間格式、貨幣格式,用戶可以在自定義配置時改寫這些默認配置,請看下面的處理過程:
~~~
//加載默認配置文件,這些文件都放在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
}
~~~
通過上面的方法加載配置信息到默認的文件,這樣我們就可以在我們沒有自定義時間信息的時候執行如下的代碼獲取對應的信息:
~~~
//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
~~~
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.3.md#template-mapfunc)template mapfunc
上面我們實現了多個語言包的管理和加載,而一些函數的實現是基于邏輯層的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等,雖然我們在邏輯層可以利用這些函數把需要的參數進行轉換后在模板層渲染的時候直接輸出,但是如果我們想在模版層直接使用這些函數該怎么實現呢?不知你是否還記得,在前面介紹模板的時候說過:Go語言的模板支持自定義模板函數,下面是我們實現的方便操作的mapfunc:
1. 文本信息
文本信息調用`Tr.Translate`來實現相應的信息轉換,mapFunc的實現如下:
~~~
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)
}
~~~
注冊函數如下:
~~~
t.Funcs(template.FuncMap{"T": I18nT})
~~~
模板中使用如下:
~~~
{{.V.Submit | T}}
~~~
1. 時間日期
時間日期調用`Tr.Time`函數來實現相應的時間轉換,mapFunc的實現如下:
~~~
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)
}
~~~
注冊函數如下:
~~~
t.Funcs(template.FuncMap{"TD": I18nTimeDate})
~~~
模板中使用如下:
~~~
{{.V.Now | TD}}
~~~
1. 貨幣信息
貨幣調用`Tr.Money`函數來實現相應的時間轉換,mapFunc的實現如下:
~~~
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)
}
~~~
注冊函數如下:
~~~
t.Funcs(template.FuncMap{"M": I18nMoney})
~~~
模板中使用如下:
~~~
{{.V.Money | M}}
~~~
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.3.md#總結)總結
通過這小節我們知道了如何實現一個多語言包的Web應用,通過自定義語言包我們可以方便的實現多語言,而且通過配置文件能夠非常方便的擴充多語言,默認情況下,go-i18n會自定加載一些公共的配置信息,例如時間、貨幣等,我們就可以非常方便的使用,同時為了支持在模板中使用這些函數,也實現了相應的模板函數,這樣就允許我們在開發Web應用的時候直接在模板中通過pipeline的方式來操作多語言包。
- 第一章 Go環境配置
- 1.1 Go安裝
- 1.2 GOPATH 與工作空間
- 1.3 Go 命令
- 1.4 Go開發工具
- 1.5 小結
- 第二章 Go語言基礎
- 2.1 你好,Go
- 2.2 Go基礎
- 2.3 流程和函數
- 2.4 struct類型
- 2.5 面向對象
- 2.6 interface
- 2.7 并發
- 2.8 總結
- 第三章 Web基礎
- 3.1 Web工作方式
- 3.2 Go搭建一個Web服務器
- 3.3 Go如何使得Web工作
- 3.4 Go的http包詳解
- 3.5 小結
- 第四章 表單
- 4.1 處理表單的輸入
- 4.2 驗證表單的輸入
- 4.3 預防跨站腳本
- 4.4 防止多次遞交表單
- 4.5 處理文件上傳
- 4.6 小結
- 第五章 訪問數據庫
- 5.1 database/sql接口
- 5.2 使用MySQL數據庫
- 5.3 使用SQLite數據庫
- 5.4 使用PostgreSQL數據庫
- 5.5 使用beedb庫進行ORM開發
- 5.6 NOSQL數據庫操作
- 5.7 小結
- 第六章 session和數據存儲
- 6.1 session和cookie
- 6.2 Go如何使用session
- 6.3 session存儲
- 6.4 預防session劫持
- 6.5 小結
- 第七章 文本處理
- 7.1 XML處理
- 7.2 JSON處理
- 7.3 正則處理
- 7.4 模板處理
- 7.5 文件操作
- 7.6 字符串處理
- 7.7 小結
- 第八章 Web服務
- 8.1 Socket編程
- 8.2 WebSocket
- 8.3 REST
- 8.4 RPC
- 8.5 小結
- 第九章 安全與加密
- 9.1 預防CSRF攻擊
- 9.2 確保輸入過濾
- 9.3 避免XSS攻擊
- 9.4 避免SQL注入
- 9.5 存儲密碼
- 9.6 加密和解密數據
- 9.7 小結
- 第十章 國際化和本地化
- 10.1 設置默認地區
- 10.2 本地化資源
- 10.3 國際化站點
- 10.4 小結
- 第十一章 錯誤處理,調試和測試
- 11.1 錯誤處理
- 11.2 使用GDB調試
- 11.3 Go怎么寫測試用例
- 11.4 小結
- 第十二章 部署與維護
- 12.1 應用日志
- 12.2 網站錯誤處理
- 12.3 應用部署
- 12.4 備份和恢復
- 12.5 小結
- 第十三章 如何設計一個Web框架
- 13.1 項目規劃
- 13.2 自定義路由器設計
- 13.3 controller設計
- 13.4 日志和配置設計
- 13.5 實現博客的增刪改
- 13.6 小結
- 第十四章 擴展Web框架
- 14.1 靜態文件支持
- 14.2 Session支持
- 14.3 表單及驗證支持
- 14.4 用戶認證
- 14.5 多語言支持
- 14.6 pprof支持
- 14.7 小結
- 附錄A 參考資料