前面小節我們介紹了如何設置Locale,設置好Locale之后我們需要解決的問題就是如何存儲相應的Locale對應的信息呢?這里面的信息包括:文本信息、時間和日期、貨幣值、圖片、包含文件以及視圖等資源。那么接下來我們將對這些信息一一進行介紹,Go語言中我們把這些格式信息存儲在JSON中,然后通過合適的方式展現出來。(接下來以中文和英文兩種語言對比舉例,存儲格式文件en.json和zh-CN.json)
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.2.md#本地化文本消息)本地化文本消息
本信息是編寫Web應用中最常用到的,也是本地化資源中最多的信息,想要以適合本地語言的方式來顯示文本信息,可行的一種方案是:建立需要的語言相應的map來維護一個key-value的關系,在輸出之前按需從適合的map中去獲取相應的文本,如下是一個簡單的示例:
~~~
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`函數來實現,請看下面的代碼:
~~~
en["how old"] ="I am %d years old"
cn["how old"] ="我今年%d歲了"
fmt.Printf(msg(lang, "how old"), 30)
~~~
上面的示例代碼僅用以演示內部的實現方案,而實際數據是存儲在JSON里面的,所以我們可以通過`json.Unmarshal`來為相應的map填充數據。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.2.md#本地化日期和時間)本地化日期和時間
因為時區的關系,同一時刻,在不同的地區,表示是不一樣的,而且因為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對象協作來獲得最終的時間。詳細的請看下面的例子(該例子采用上面例子的一些變量):
~~~
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))
~~~
我們可以通過類似處理文本格式的方式來解決時間格式的問題,舉例如下:
~~~
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
}
~~~
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.2.md#本地化貨幣值)本地化貨幣值
各個地區的貨幣表示也不一樣,處理方式也與日期差不多,細節請看下面代碼:
~~~
en["money"] ="USD %d"
cn["money"] ="¥%d元"
fmt.Println(date(msg(lang,"date_format"),100))
func money_format(fomate string,money int64) string{
return fmt.Sprintf(fomate,money)
}
~~~
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.2.md#本地化視圖和資源)本地化視圖和資源
我們可能會根據Locale的不同來展示視圖,這些視圖包含不同的圖片、css、js等各種靜態資源。那么應如何來處理這些信息呢?首先我們應按locale來組織文件信息,請看下面的文件目錄安排:
~~~
views
|--en //英文模板
|--images //存儲圖片信息
|--js //存儲JS文件
|--css //存儲css文件
index.tpl //用戶首頁
login.tpl //登陸首頁
|--zh-CN //中文模板
|--images
|--js
|--css
index.tpl
login.tpl
~~~
有了這個目錄結構后我們就可以在渲染的地方這樣來實現代碼:
~~~
s1, _ := template.ParseFiles("views"+lang+"index.tpl")
VV.Lang=lang
s1.Execute(os.Stdout, VV)
~~~
而對于里面的index.tpl里面的資源設置如下:
~~~
// js文件
<script type="text/javascript" src="views/{{.VV.Lang}}/js/jquery/jquery-1.8.0.min.js"></script>
// css文件
<link href="views/{{.VV.Lang}}/css/bootstrap-responsive.min.css" rel="stylesheet">
// 圖片文件
<img src="views/{{.VV.Lang}}/images/btn.png">
~~~
采用這種方式來本地化視圖以及資源時,我們就可以很容易的進行擴展了。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.2.md#總結)總結
本小節介紹了如何使用及存儲本地資源,有時需要通過轉換函數來實現,有時通過lang來設置,但是最終都是通過key-value的方式來存儲Locale對應的數據,在需要時取出相應于Locale的信息后,如果是文本信息就直接輸出,如果是時間日期或者貨幣,則需要先通過`fmt.Printf`或其他格式化函數來處理,而對于不同Locale的視圖和資源則是最簡單的,只要在路徑里面增加lang就可以實現了。
- 第一章 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 參考資料