國際化和本地化
為了適應經濟的全球一體化,作為開發者,我們需要開發出支持多國語言、國際化的Web應用,即同樣的頁面在不同的語言環境下需要顯示不同的效果,也就是說應用程式在運行時能夠根據請求所來自的地域與語言的不同而顯示不同的用戶界面,這樣,當需要在應用程式中添加對新的語言的支持時,無需修改應用程式的代碼,只需要增加語言包即可實作,
國際化與本地化(Internationalization and localization,通常用i18n和L10N表示),國際化是將針對某個地區設計的程式進行重構,以使它能夠在更多地區使用,本地化是指在一個面向國際化的程式中增加對新地區的支持,
所謂的國際化:就是根據特定的locale資訊,提取與之相應的字串或其它一些東西(比如時間和貨幣的格式)等等,這涉及到三個問題:
1、如何確定locale,
2、如何保存與locale相關的字串或其它資訊,
3、如何根據locale提取字串和其它相應的資訊,
設定默認地區
什么是Locale
Locale是一組描述世界上某一特定區域文本格式和語言習慣的設定的集合,locale名通常由三個部分組成:第一部分,是一個強制性的,表示語言的縮寫,例如"en"表示英文或"zh"表示中文,第二部分,跟在一個下劃線之后,是一個可選的國家說明符,用于區分講同一種語言的不同國家,例如"en_US"表示美國英語,而"en_UK"表示英國英語,最后一部分,跟在一個句點之后,是可選的字符集說明符,例如"zh_CN.gb2312"表示中國使用gb2312字符集,
本地化資源
前面我們介紹了如何設定Locale,設定好Locale之后我們需要解決的問題就是如何存盤相應的Locale對應的資訊呢?這里面的資訊包括:文本資訊、時間和日期、貨幣值、圖片、包含檔案以及視圖等資源,那么接下來我們將對這些資訊一一進行介紹,Go語言中我們把這些格式資訊存盤在JSON中,然后通過合適的方式展現出來
本地化文本訊息
文本資訊是撰寫Web應用中最常用到的,也是本地化資源中最多的資訊,想要以適合本地語言的方式來顯示文本資訊,可行的一種方案是:建立需要的語言相應的map來維護一個key-value的關系,在輸出之前按需從適合的map中去獲取相應的文本,
有些時候僅是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)
本地化日期和時間
因為時區的關系,同一時刻,在不同的地區,表示是不一樣的,而且因為Locale的關系,時間格式也不盡相同,例如中文環境下可能顯示:2012年10月24日 星期三 23時11分13秒 CST,而在英文環境下可能顯示:Wed Oct 24 23:11:13 CST 2012,這里面我們需要解決兩點:
- 時區問題
- 格式問題
本地化視圖和資源
我們可能會根據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=https://www.cnblogs.com/ygjzs/p/"views/{{.Lang}}/js/jquery/jquery-1.8.0.min.js"></script>
// css檔案
<link href="views/{{.Lang}}/css/bootstrap-responsive.min.css" rel="stylesheet">
// 圖片檔案
采用這種方式來本地化視圖以及資源時,我們就可以很容易的進行擴展了,
使用及存盤本地資源,有時需要通過轉換函式來實作,有時通過lang來設定,但是最終都是通過key-value的方式來存盤Locale對應的資料,在需要時取出相應于Locale的資訊后,如果是文本資訊就直接輸出,如果是時間日期或者貨幣,則需要先通過fmt.Printf或其他格式化函式來處理,而對于不同Locale的視圖和資源則是最簡單的,只要在路徑里面增加lang就可以實作了,
國際化站點
前面介紹了如何處理本地化資源,即Locale一個相應的組態檔,那么如果處理多個的本地化資源呢?而對于一些我們經常用到的例如:簡單的文本翻譯、時間日期、數字等如果處理呢?本小節將一一解決這些問題,
管理多個本地包
在開發一個應用的時候,首先我們要決定是只支持一種語言,還是多種語言,如果要支持多種語言,我們則需要制定一個組織結構,以方便將來更多語言的添加,在此我們設計如下:Locale有關的檔案放置在config/locales下,假設你要支持中文和英文,那么你需要在這個檔案夾下放置en.json和zh.json,
自動加載本地包
上面我們介紹了如何自動加載自定義語言包,其實go-i18n庫已經預加載了很多默認的格式資訊.
emplate mapfunc
上面實作了多個語言包的管理和加載,而一些函式的實作是基于邏輯層的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等,雖然我們在邏輯層可以利用這些函式把需要的引數進行轉換后在模板層渲染的時候直接輸出,但是如果我們想在模版層直接使用這些函式該怎么實作呢?不知你是否還記得,在前面介紹模板的時候說過:Go語言的模板支持自定義模板函式,下面是我們實作的方便操作的mapfunc:
文本資訊
文本資訊呼叫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}}
如何實作一個多語言包的Web應用,通過自定義語言包我們可以方便的實作多語言,而且通過組態檔能夠非常方便的擴充多語言,默認情況下,go-i18n會自定加載一些公共的配置資訊,例如時間、貨幣等,我們就可以非常方便的使用,同時為了支持在模板中使用這些函式,也實作了相應的模板函式,這樣就允許我們在開發Web應用的時候直接在模板中通過pipeline的方式來操作多語言包,
鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/49409.html
標籤:Go
上一篇:Jaeger容器化部署
下一篇:goweb-錯誤處理,除錯和測驗
