- 文档
- 教程
【免费下载链接】build-web-application-with-golang
A golang ebook intro how to build a web with golang
本文是「Go Web 程式設計」(build-web-application-with-golang)一書第十章「國際化和本地化」的開篇實戰指南,核心解決國際化(i18n)中的第一個關鍵問題:如何確定並設定 Locale。讀完本文,你將掌握 Locale 的命名規範,以及透過域名、URL 參數、客戶端資訊三種途徑設定使用者地區的完整方案,為後續的本地化資源與國際化站點打下基礎。
什麼是 Locale
Locale 是一組描述世界上某一特定區域文字格式和語言習慣的設定的集合。它決定了應用程式在執行時,該以什麼語言、什麼時間格式、什麼貨幣符號來向使用者呈現內容。
一個完整的 locale 名通常由三個部分組成:
- 語言縮寫(強制):表示語言的縮寫,例如
en表示英文、zh表示中文。 - 國家說明符(可選):跟在一個下劃線之後,用於區分講同一種語言的不同國家,例如
en_US表示美國英語,而en_UK表示英國英語。 - 字符集說明符(可選):跟在一個句點之後,例如
zh_CN.gb2312表示中國使用 gb2312 字符集。
在 Linux 和 Solaris 系統中可以透過
locale -a命令列舉所有支援的地區名,讀者可以看到這些地區名的命名規範。對於 BSD 等系統,沒有 locale 命令,但是地區資訊儲存在/usr/share/locale中。
Go 語言預設採用 UTF-8 編碼集,所以我們實現 i18n 時不考慮第三部分(字符集說明符),接下來我們都採用 locale 描述的前面兩部分來作為 i18n 標準的 locale 名,例如en、zh-CN、zh-TW。
設定 Locale 的三種主要途徑
有了上面對 locale 的定義,我們就需要根據使用者的資訊(訪問資訊、個人資訊、訪問域名等)來設定與之相關的 locale。這一節介紹三種主流的設定方式。
透過域名設定 Locale
設定 Locale 的辦法之一是在應用執行的時候採用域名分級的方式。例如,我們採用www.asta.com當做英文站(預設站),而把域名www.asta.cn當做中文站。這樣透過在應用裡面設定域名和相應的 locale 的對應關係,就可以設定好地區。
這種處理方式有幾點好處:
- 透過 URL 就可以很明顯的識別
- 使用者可以透過域名很直觀的知道將訪問哪種語言的站點
- 在 Go 程式中實現非常簡單方便,透過一個 map 就可以實現
- 有利於搜尋引擎抓取,能夠提高站點的 SEO
我們可以透過下面的程式碼來實現域名的對應 locale:
if r.Host == "www.asta.com" { i18n.SetLocale("en") } else if r.Host == "www.asta.cn" { i18n.SetLocale("zh-CN") } else if r.Host == "www.asta.tw" { i18n.SetLocale("zh-TW") }除了整域名設定地區之外,我們還可以透過子域名來設定地區,例如en.asta.com表示英文站點,cn.asta.com表示中文站點。實現程式碼如下所示:
prefix := strings.Split(r.Host, ".") if prefix[0] == "en" { i18n.SetLocale("en") } else if prefix[0] == "cn" { i18n.SetLocale("zh-CN") } else if prefix[0] == "tw" { i18n.SetLocale("zh-TW") }透過域名設定 Locale 有如上所示的優點,但是一般開發 Web 應用的時候不會採用這種方式,因為:
- 域名成本比較高,開發一個 Locale 就需要一個域名,而且往往統一名稱的域名不一定能申請得到;
- 我們不願意為每個站點去本地化一個配置。
因此更常見的做法是採用 URL 後面帶參數的方式,請看下面的介紹。
從 URL 參數設定 Locale
目前最常用的設定 Locale 的方式是在 URL 裡面帶上參數,例如www.asta.com/hello?locale=zh或者www.asta.com/zh/hello。這樣我們就可以設定地區:i18n.SetLocale(params["locale"])。
這種設定方式幾乎擁有前面講的透過域名設定 Locale 的所有優點,它採用 RESTful 的方式,使得我們不需要增加額外的方法來處理。但是這種方式需要在每一個 link 裡面增加相應的參數locale,這也許有點複雜而且有時候甚至相當的繁瑣。不過我們可以寫一個通用的函式url,讓所有的 link 地址都透過這個函式來產生,然後在這個函式裡面增加locale=params["locale"]參數來緩解一下。
也許我們希望 URL 地址看上去更加 RESTful 一點,例如:www.asta.com/en/books(英文站點)和www.asta.com/zh/books(中文站點)。這種方式的 URL 更加有利於 SEO,而且對於使用者也比較友好,能夠透過 URL 直觀的知道訪問的站點。那麼這樣的 URL 地址可以透過 router 來取得 locale(參考本書第 8 章 REST 小節裡面介紹的 router 外掛實現):
mux.Get("/:locale/books", listbook)從客戶端資訊設定地區
在一些特殊的情況下,我們需要根據客戶端的資訊而不是透過 URL 來設定 Locale,這些資訊可能來自於客戶端設定的喜好語言(瀏覽器中設定)、使用者的 IP 地址、使用者在註冊的時候填寫的所在地資訊等。這種方式比較適合以 Web 為基礎的應用。
Accept-Language
客戶端請求的時候在 HTTP 頭資訊裡面有Accept-Language,一般的客戶端都會設定該資訊,下面是 Go 語言實現的一個簡單的根據Accept-Language實現設定地區的程式碼:
AL := r.Header.Get("Accept-Language") if AL == "en" { i18n.SetLocale("en") } else if AL == "zh-CN" { i18n.SetLocale("zh-CN") } else if AL == "zh-TW" { i18n.SetLocale("zh-TW") }當然在實際應用中,可能需要更加嚴格的判斷來進行設定地區,例如Accept-Language頭通常攜帶多個帶權重的語言選項(如zh-CN,zh;q=0.9,en;q=0.8),需要按優先級解析後再決定使用哪一個 locale。
IP 地址
另一種根據客戶端來設定地區的方式是使用者訪問的 IP:我們根據相應的 IP 函式庫,把訪問的 IP 對應到地區。目前全球比較常用的就是 GeoIP Lite Country 這個函式庫。這種設定地區的機制非常簡單,我們只需要根據 IP 資料庫查詢使用者的 IP,然後回傳國家地區,根據回傳的結果設定對應的地區即可。
使用者 profile
當然你也可以讓使用者根據你提供的下拉選單或者別的方式設定相應的 locale,然後將使用者輸入的資訊儲存到與它帳號相關的 profile 中。當使用者再次登陸的時候,把這個設定複寫到 locale 設定中,這樣就可以保證該使用者每次訪問都是基於自己先前設定的 locale 來獲得頁面——這是「記住使用者語言偏好」最直接的做法。
設定 Locale 之後:i18n 的完整閉環
「確定 locale」只是國際化的第一步。在第十章第 10.0 節(國際化和本地化)中明確指出,完整的 i18n 涉及三個問題:
- 如何確定 locale;
- 如何儲存與 locale 相關的字串或其它資訊;
- 如何根據 locale 提取字串和其它相應的資訊。
本節(設定預設地區)解決的是第一個問題;確定好 locale 之後,本地化資源 小節會介紹如何用 key-value 結構儲存文字、時間日期、貨幣值以及按語言劃分的視圖與靜態資源;國際化站點 小節則透過go-i18n套件(i18n.NewLocale()配合Tr.LoadPath("config/locales")載入語言套件、Tr.SetLocale("zh")切換語言、Tr.Translate/Tr.Time/Tr.Money提取對應內容)實現完整的國際化 Web 站點,並提供T、TD、M等範本函式在模板中直接使用。
可以看出,無論採用哪一種設定途徑,最終都會收斂到一個統一的入口:把使用者對應的 locale 寫入 i18n 套件(如i18n.SetLocale/Tr.SetLocale),之後所有的本地化輸出都以此為基準。這正是「設定預設地區」這一環節在整個 i18n 架構中的樞紐地位。
如何選擇合適的設定方式
三種途徑各有適用場景,可以根據需求取捨:
| 設定途徑 | 適用場景 | 優點 | 注意點 |
|---|---|---|---|
| 域名 / 子域名 | 多語言站點分站部署 | URL 直觀、SEO 友好、Go 中 map 即可實現 | 域名成本高,每個語言需獨立域名 |
| URL 參數(query 或 RESTful 路徑) | 單站點多語言切換 | 實現簡單、SEO 友好、無需額外域名 | 每個 link 需攜帶 locale 參數,可用通用 url 函式緩解 |
| 客戶端資訊(Accept-Language / IP / profile) | Web 為基礎的應用 | 無需使用者操作即可自動匹配 | Accept-Language 需嚴格解析;IP 需引入 GeoIP 資料庫;profile 需登入體系支撐 |
實務上,很多國際化站點會將「URL 路徑優先級最高、Accept-Language 作為預設兜底、profile 作為登入使用者的個性化覆寫」結合起來使用,構成完整的 locale 決策鏈。
總結
透過上面的介紹可知,設定 Locale 可以有很多種方式:透過域名(整域名或子域名)、透過 URL 參數(query 或 RESTful 路徑)、透過客戶端資訊(Accept-Language、IP 地址、使用者 profile)。我們應該根據需求的不同來選擇不同的設定 Locale 的方法,以讓使用者能以它最熟悉的方式獲得我們提供的服務,提高應用的使用者友好性。
本章後續內容:本地化資源(文字、時間日期、貨幣、視圖的本地化)與 國際化站點(基於 go-i18n 的多語言套件管理),最終在 小結 中收束為完整的 Go i18n 開源方案。
links
- 目錄
- 上一節:國際化和本地化
- 下一節:本地化資源
- 文档
- 教程
【免费下载链接】build-web-application-with-golang
A golang ebook intro how to build a web with golang
相关推荐
OpenDesign 設計系統包實戰:以 Uber 風格為藍本的黑白膠囊化設計規範與 Token 實現解析
OpenDesign 設計系統包實戰:以 Uber 風格為藍本的黑白膠囊化設計規範與 Token 實現解析 本篇指南以 design systems/uber/
AI 应用人工智能AI 技能设计系统媒体生成Go Web 程式設計實戰:RPC 遠端過程呼叫的 HTTP、TCP 與 JSON-RPC 三種實現
Go Web 程式設計實戰:RPC 遠端過程呼叫的 HTTP、TCP 與 JSON RPC 三種實現 本文以《build web application wit
文档教程Go 語言流程控制與函式設計:以 build-web-application-with-golang 第 2.3 節為核心的實戰指南
Go 語言流程控制與函式設計:以 build web application with golang 第 2.3 節為核心的實戰指南 本篇技術指南圍繞開源電子書
文档教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考