beego的I18n模塊

2023-11-21 10:46 更新

國際化介紹

i18n 模塊主要用于實現(xiàn)站點或應(yīng)用的國際化功能,實現(xiàn)多語言界面與反饋,增強用戶體驗。像 Go Walker 和 beego 官網(wǎng) 即是采用了該模塊實現(xiàn)了中文與英文的雙語界面。

您可以通過以下方式安裝該模塊:

go get github.com/beego/i18n

i18n 使用

首先,您需要導(dǎo)入該包:

import (
    "github.com/beego/i18n"
)

該模塊主要采用的是鍵值對的形式,非常類似 INI 格式的配置文件,但又在此基礎(chǔ)上增強了一些功能。每個語種均對應(yīng)一個本地化文件,例如 beego 官網(wǎng)的 conf 目錄下就有 locale_en-US.ini 和 locale_zh-CN.ini 兩個本地化文件。

本地化文件的文件名和后綴是隨意的,不過我們建議您采用與 beego 官網(wǎng)相同的風格來對它們命名。

最簡實例

下面是兩個最簡單的本地化文件示例:

文件 locale_en-US.ini:

hi = hello
bye = goodbye

文件 locale_zh-CN.ini:

hi = 您好
bye = 再見

在控制器中使用

對于每個請求,beego 都會采用單獨的 goroutine 來處理,因此可以對每個控制器匿名嵌入一個 i18n.Locale 結(jié)構(gòu)用于處理當前請求的本地化響應(yīng)。這個要求您能夠理解 beego 的 baseController 理念和使用 Prepare 方法,具體可參考 beego 官網(wǎng)的控制器源碼部分 routers/router.go。

接受請求之后,在 baseController 的 Prepare 方法內(nèi)進行語言處理,這樣便可應(yīng)用后所有其它控制器內(nèi)而無需重復(fù)編寫代碼。

注冊本地化文件

以下代碼摘取自 beego 官網(wǎng)源碼 routers/init.go:

// Initialized language type list.
langs := strings.Split(beego.AppConfig.String("lang::types"), "|")
names := strings.Split(beego.AppConfig.String("lang::names"), "|")
langTypes = make([]*langType, 0, len(langs))
for i, v := range langs {
    langTypes = append(langTypes, &langType{
        Lang: v,
        Name: names[i],
    })
}

for _, lang := range langs {
    beego.Trace("Loading language: " + lang)
    if err := i18n.SetMessage(lang, "conf/"+"locale_"+lang+".ini"); err != nil {
        beego.Error("Fail to set message file: " + err.Error())
        return
    }
}

在這段代碼中,我們首先從配置文件中獲取我們需要支持的語言種類,例如官網(wǎng)支持的語言有 en-US 和 zh-CN。接著初始化了一個用于實現(xiàn)用戶自由切換語言的 slice(此處不做討論),最后,根據(jù)我們需要支持的語言種類,采用一個循環(huán)內(nèi)調(diào)用 i18n.SetMessage 加載所有本地化文件。此時,您應(yīng)該明白為什么我們推薦您采用標準化的形式命名您的本地化文件。

初始化控制器語言

下面的代碼摘取自 beego 官網(wǎng)的控制器語言處理部分 routers/router.go,依次根據(jù) URL 指定、Cookies 和瀏覽器 Accept-Language 來獲取用戶語言選項,然后設(shè)置控制器級別的語言。

// setLangVer sets site language version.
func (this *baseRouter) setLangVer() bool {
    isNeedRedir := false
    hasCookie := false

    // 1. Check URL arguments.
    lang := this.Input().Get("lang")

    // 2. Get language information from cookies.
    if len(lang) == 0 {
        lang = this.Ctx.GetCookie("lang")
        hasCookie = true
    } else {
        isNeedRedir = true
    }

    // Check again in case someone modify by purpose.
    if !i18n.IsExist(lang) {
        lang = ""
        isNeedRedir = false
        hasCookie = false
    }

    // 3. Get language information from 'Accept-Language'.
    if len(lang) == 0 {
        al := this.Ctx.Request.Header.Get("Accept-Language")
        if len(al) > 4 {
            al = al[:5] // Only compare first 5 letters.
            if i18n.IsExist(al) {
                lang = al
            }
        }
    }

    // 4. Default language is English.
    if len(lang) == 0 {
        lang = "en-US"
        isNeedRedir = false
    }

    curLang := langType{
        Lang: lang,
    }

    // Save language information in cookies.
    if !hasCookie {
        this.Ctx.SetCookie("lang", curLang.Lang, 1<<31-1, "/")
    }

    restLangs := make([]*langType, 0, len(langTypes)-1)
    for _, v := range langTypes {
        if lang != v.Lang {
            restLangs = append(restLangs, v)
        } else {
            curLang.Name = v.Name
        }
    }

    // Set language properties.
    this.Lang = lang
    this.Data["Lang"] = curLang.Lang
    this.Data["CurLang"] = curLang.Name
    this.Data["RestLangs"] = restLangs

    return isNeedRedir
}

其中,isNeedRedir 變量用于表示用戶是否是通過 URL 指定來決定語言選項的,為了保持 URL 整潔,官網(wǎng)在遇到這種情況時自動將語言選項設(shè)置到 Cookies 中然后重定向。

代碼 this.Data["Lang"] = curLang.Lang 是將用戶語言選項設(shè)置到名為 Lang 的模板變量中,使得能夠在模板中處理語言問題。

以下兩行:

this.Data["CurLang"] = curLang.Name
this.Data["RestLangs"] = restLangs

主要用于實現(xiàn)用戶自由切換語言,具體實現(xiàn)原理請參考 beego 官網(wǎng)源碼。

控制器語言處理

當作為匿名字段嵌入到 baseController 之后,直接通過 this.Tr(format string, args ...interface{}) 即可進行語言處理。

在模板中使用

通過在控制器中傳入一個 Lang 變量來指示語言選項后,就可以在模板中進行本地化處理,不過在這之前,需要先注冊一個模板函數(shù)。

以下代碼摘取自 beego 官網(wǎng)源碼 beeweb.go:

beego.AddFuncMap("i18n", i18n.Tr)

注冊完成之后,便可配合 Lang 變量在模板中進行語言處理:

{{i18n .Lang "hi%d" 12}}

以上代碼會輸出:

  • 英文 en-US:hello12
  • 中文 zh-CN:您好12

分區(qū)功能

針對不同頁面,同一個鍵的名稱很可能會對應(yīng)不同的含義。因此,i18n 模塊還利用 INI 格式配置文件的節(jié)特性來實現(xiàn)分區(qū)功能。

例如,同樣是鍵名 about,在首頁需要顯示為 關(guān)于,而在關(guān)于頁面需要顯示為 關(guān)于我們,則可以通過分區(qū)功能來實現(xiàn)。

本地化文件中的內(nèi)容:

about = About

[about]
about = About Us

獲取首頁的 about:

{{i18n .Lang "about"}}

獲取關(guān)于頁面的 about:

{{i18n .Lang "about.about"}}

歧義處理

由于 . 是作為分區(qū)的標志,所以當您的鍵名出現(xiàn)該符號的時候,會出現(xiàn)歧義導(dǎo)致語言處理失敗。這時,您只需要在整個鍵名前加上一個額外的 . 即可避免歧義。

例如,我們的鍵名為 about.,為了避免歧義,我們需要使用:

{{i18n .Lang ".about."}}

來獲取正確的本地化結(jié)果。

命令行工具

i18n 模塊提供命令行工具 beei18n 來幫助簡化開發(fā)中的一些步驟。您可以通過以下方式安裝:

go get github.com/beego/i18n/beei18n

同步本地化文件

命令 sync 允許您使用已經(jīng)創(chuàng)建好的一個本地化文件為模板,創(chuàng)建或同步其它的本地化文件:

beei18n sync srouce_file.ini other1.ini other2.ini

該命令可以同時操作 1 個或多個文件。

其它說明

如果未找到相應(yīng)鍵的對應(yīng)值,則會輸出鍵的原字符串。例如:當鍵為 hi 但未在本地化文件中找到以該字符串命名的鍵,則會將 hi 作為字符串返回給調(diào)用者。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號