i18n 模块

原文:https://beego.wiki/docs/module/i18n/

i18n Module - i18n 模块

Introduction to i18n - i18n 简介

This module is mainly used for i18n of sites and applications, which provides multiple-language options to users, improve user experience. Sites like Go Walker and beego.wiki use this module to implement Chinese and English user interfaces.

​ 本模块主要用于网站和应用程序的 i18n,为用户提供多语言选项,提升用户体验。像 Go Walker 和 beego.wiki 这样的网站就使用了本模块来实现中英文用户界面。

You can use the following command to install this module:

​ 您可以使用以下命令安装本模块:

go get github.com/beego/i18n

i18n Usage - i18n 用法

First of all, you have to import this package:

​ 首先,您必须导入此包:

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

The format of locale files is very much like the INI format configuration file, which is basically key-value pairs. But this module has some improvements. Every language corresponds to a locale file, for example, under conf folder of beego.wiki, there are two files called locale_en-US.ini and locale_zh-CN.ini.

​ 区域设置文件的格式非常类似于 INI 格式配置文件,基本上是键值对。但本模块做了一些改进。每种语言对应一个区域设置文件,例如,在 beego.wiki 的 conf 文件夹下,有两个文件,分别称为 locale_en-US.inilocale_zh-CN.ini

The name and extensions of locale files can be anything, but we strongly recommend you to follow the style of beego.wiki.

​ 区域设置文件的名称和扩展名可以是任意内容,但我们强烈建议您遵循 beego.wiki 的样式。

Minimal example 最小示例

Here are two simplest locale file examples:

​ 以下是两个最简单的区域设置文件示例:

File locale_en-US.ini:

​ 文件 locale_en-US.ini

hi = hello
bye = goodbye

File locale_zh-CN.ini:

​ 文件 locale_zh-CN.ini

hi = 您好
bye = 再见

Use in controller 在控制器中使用

For every request, Beego uses individual goroutines to handle the request; therefore, you can embed an i18n.Locale as an anonymous field to process locale operations of the current request. This requires that you understand the idea of baseController and Prepare method. See source file routers/router.go of beego.wiki for more details.

​ 对于每个请求,Beego 使用单独的 goroutine 来处理请求;因此,您可以将 i18n.Locale 嵌入为匿名字段来处理当前请求的区域设置操作。这要求您了解 baseControllerPrepare 方法的概念。有关更多详细信息,请参阅 beego.wiki 的源文件 routers/router.go

After accepting the request, use the Prepare method of baseController to do language operations, which you only need to write the same code once and use it in all the upper level controllers.

​ 接受请求后,使用 baseControllerPrepare 方法执行语言操作,您只需编写一次相同的代码并在所有上层控制器中使用它。

Register locale files 注册区域设置文件

The following code is from beego.wiki source file routers/init.go:

​ 以下代码来自 beego.wiki 源文件 routers/init.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 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
	}
}

In this piece of code, we get languages that we want to support in the configuration file, in this case, we have en-US and zh-CN. Then we initialize a slice for users to change language option(not discussed here). Finally, we call the i18n.SetMessage function in a loop to load all the locale files. Here you can see why we recommend the you use the naming conventions of beego.wiki for locale files.

​ 在这段代码中,我们获取了我们希望在配置文件中支持的语言,在本例中,我们有 en-USzh-CN 。然后,我们初始化一个切片供用户更改语言选项(此处未讨论)。最后,我们循环调用 i18n.SetMessage 函数来加载所有区域设置文件。在这里,您可以看到我们为什么建议您对区域设置文件使用 beego.wiki 的命名约定。

Initialize controller language 初始化控制器语言

The following code is from the beego.wiki source file routers/router.go, which decides on which user language option to use in the following order: 1: URL specified 2: Cookies and 3: browser Accept-Language.

​ 以下代码来自 beego.wiki 源文件 routers/router.go ,它决定了按以下顺序使用哪种用户语言选项:1:URL 指定 2:Cookies 和 3:浏览器 Accept-Language

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 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 on 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
}

The variable isNeedRedir indicates whether user uses URL to specify the language option. To keep the URL clean, beego.wiki automatically sets the value in cookies and redirect.

​ 变量 isNeedRedir 指示用户是否使用 URL 指定语言选项。为了保持 URL 清晰,beego.wiki 会自动在 cookie 中设置值并重定向。

The line this.Data["Lang"] = curLang.Lang sets user language option to template variable Lang so that we can handle language in template files.

​ 行 this.Data["Lang"] = curLang.Lang 将用户语言选项设置为模板变量 Lang ,以便我们可以在模板文件中处理语言。

Following two lines:

​ 以下两行:

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

For users to change language option, see beego.wiki source code for more details.

​ 有关用户如何更改语言选项,请参阅 beego.wiki 源代码以了解更多详细信息。

Handle language in controller 在控制器中处理语言

While the i18n.Locale is an anonymous field to be embedded in baseController, we can use this.Tr(format string, args ...interface{}) to handle language in controller.

​ 虽然 i18n.Locale 是要嵌入到 baseController 中的匿名字段,但我们可以使用 this.Tr(format string, args ...interface{}) 在控制器中处理语言。

Handle language in template 在模板中处理语言

By passing template variable Lang to indicate language option, you are able to do localization in template. But before that, you need to register a template function.

​ 通过传递模板变量 Lang 来指示语言选项,您可以在模板中执行本地化。但在此之前,您需要注册一个模板函数。

Following code is from beego.wiki source file beeweb.go:

​ 以下代码来自 beego.wiki 源文件 beeweb.go

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

After that, do the following with Lang to handle language:

​ 然后,使用 Lang 执行以下操作以处理语言:

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

Code above will produce:

​ 上面的代码将生成:

  • English en-UShello12 英语 en-UShello12
  • Chinese zh-CN您好12 中文 zh-CN您好12

Section 部分

For different pages, one key may map to different values. Therefore, i18n module also uses the section feature of INI format configuration to achieve section separation.

​ 对于不同的页面,一个键可能映射到不同的值。因此,i18n 模块还使用 INI 格式配置的部分功能来实现部分分离。

For example, the key name is about, and we want to show About in the home page and About Us in about page. Then you can do following:

​ 例如,键名为 about ,我们希望在主页中显示 About ,在关于页面中显示 About Us 。然后,您可以执行以下操作:

Content in locale file:

​ 区域设置文件中的内容:

about = About

[about]
about = About Us

Get about in home page:

​ 在主页中获取 about

{{i18n .Lang "about"}}

Get about in about page:

​ 在关于页面中获取 about

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

Ambiguity 歧义

Because dot . denotes a section in both INI parser and locale files, when your key name contains . this will cause ambiguity. To avoid ambiguity, you just need to add one more . in front of the key.

​ 由于点 . 在 INI 解析器和区域设置文件中都表示一个节,因此当您的键名包含 . 时,这将导致歧义。为了避免歧义,您只需在键的前面再添加一个 .

For example, the key name is about., then we can use:

​ 例如,键名为 about. ,那么我们可以使用:

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

to get the desired result.

​ 来获取所需的结果。

Helper tool 辅助工具

Module i18n provides a command line helper tool beei18n to simplify the steps in your development. You can install it as follows:

​ 模块 i18n 提供了一个命令行辅助工具 beei18n,以简化您的开发中的步骤。您可以按如下方式安装它:

go get github.com/beego/i18n/beei18n

Sync locale files 同步区域设置文件

Command sync allows you use a exist local file as the template to create or sync other locale files:

​ 命令 sync 允许您使用一个现有的本地文件作为模板来创建或同步其他区域设置文件:

beei18n sync source_file.ini other1.ini other2.ini

This command can operate on 1 or more files in one command.

​ 此命令可以在一个命令中对 1 个或多个文件进行操作。

More information 更多信息

If the key does not exist, then i18n will return the key string to caller. For instance, when key name is hi and it does not exist in locale file, it will simply return hi as output.

​ 如果键不存在,则 i18n 会将键字符串返回给调用方。例如,当键名为 hi 且它不存在于区域设置文件中时,它将简单地返回 hi 作为输出。

最后修改 February 4, 2024: 更新 (87c2937)