golang国际化站点
管理多個本地包
在開發一個應用的時候,首先我們要決定是只支持一種語言,還是多種語言,如果要支持多種語言,我們則需要制定一個組織結構,以方便將來更多語言的添加。在此我們設計如下:Locale有關的文件放置在config/locales下,假設你要支持中文和英文,那么你需要在這個文件夾下放置en.json和zh.json。大概的內容如下所示:
# zh.json{ "zh": {"submit": "提交","create": "創建"} }#en.json{ "en": {"submit": "Submit","create": "Create"} }為了支持國際化,在此我們使用了一個國際化相關的包——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")) //輸出“遞交”自動加載本地包
上面我們介紹了如何自動加載自定義語言包,其實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 CSTfmt.Println(Tr.Time(time.Now(),"long")) //輸出:2009年1月08日fmt.Println(Tr.Money(11.11)) //輸出:¥11.11template mapfunc
上面我們實現了多個語言包的管理和加載,而一些函數的實現是基于邏輯層的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等,雖然我們在邏輯層可以利用這些函數把需要的參數進行轉換后在模板層渲染的時候直接輸出,但是如果我們想在模版層直接使用這些函數該怎么實現呢?不知你是否還記得,在前面介紹模板的時候說過:Go語言的模板支持自定義模板函數,下面是我們實現的方便操作的mapfunc:
文本信息調用Tr.Translate來實現相應的信息轉換,mapFunc的實現如下:
func I18nT(args ...interface{}) string {ok := falsevar s stringif 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}}時間日期調用Tr.Time函數來實現相應的時間轉換,mapFunc的實現如下:
func I18nTimeDate(args ...interface{}) string {ok := falsevar s stringif 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}}貨幣調用Tr.Money函數來實現相應的時間轉換,mapFunc的實現如下:
func I18nMoney(args ...interface{}) string {ok := falsevar s stringif 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}}總結
以上是生活随笔為你收集整理的golang国际化站点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: go web本地化资源
- 下一篇: golang错误处理