beego的I18n模塊

2023-11-21 10:46 更新

國際化介紹

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

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

go get github.com/beego/i18n

i18n 使用

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

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

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

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

最簡(jiǎn)實(shí)例

下面是兩個(gè)最簡(jiǎn)單的本地化文件示例:

文件 locale_en-US.ini:

hi = hello
bye = goodbye

文件 locale_zh-CN.ini:

hi = 您好
bye = 再見

在控制器中使用

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

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

注冊(cè)本地化文件

以下代碼摘取自 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。接著初始化了一個(gè)用于實(shí)現(xiàn)用戶自由切換語言的 slice(此處不做討論),最后,根據(jù)我們需要支持的語言種類,采用一個(gè)循環(huán)內(nèi)調(diào)用 i18n.SetMessage 加載所有本地化文件。此時(shí),您應(yīng)該明白為什么我們推薦您采用標(biāo)準(zhǔn)化的形式命名您的本地化文件。

初始化控制器語言

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

// 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 指定來決定語言選項(xiàng)的,為了保持 URL 整潔,官網(wǎng)在遇到這種情況時(shí)自動(dòng)將語言選項(xiàng)設(shè)置到 Cookies 中然后重定向。

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

以下兩行:

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

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

控制器語言處理

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

在模板中使用

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

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

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

注冊(cè)完成之后,便可配合 Lang 變量在模板中進(jìn)行語言處理:

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

以上代碼會(huì)輸出:

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

分區(qū)功能

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

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

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

about = About

[about]
about = About Us

獲取首頁的 about:

{{i18n .Lang "about"}}

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

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

歧義處理

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

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

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

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

命令行工具

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

go get github.com/beego/i18n/beei18n

同步本地化文件

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

beei18n sync srouce_file.ini other1.ini other2.ini

該命令可以同時(shí)操作 1 個(gè)或多個(gè)文件。

其它說明

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

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)