进阶 www.iris-go.com 2026-10-20 02:39:14 · 18 阅读
第13章 Iris 框架中的国际化(i18n)与本地化(L10n)实现指南
国际化和本地化
本地化功能提供了一种便捷的机制,让你能在应用中轻松支持多语言。语言字符串存储在 ./locales 目录下的文件中。该目录中应为应用支持的每种语言创建一个子目录:
bash
│ main.go
└───locales
├───el-GR
│ home.yml
├───en-US
│ home.yml
└───zh-CN
home.yml
应用的默认语言是第一个注册的语言。 go app := iris.New() // 第一个参数:Glob 文件路径模式 // 第二个可变参数:可选的语言标签, // 第一个即为默认/回退语言。 app.I18n.Load("./locales/*/*", "en-US", "el-GR", "zh-CN")
或者,如果按文件名加载所有语言: go app.I18n.Load("./locales/*/*") // 然后通过以下方式设置默认语言: app.I18n.SetDefault("en-US")
嵌入本地化资源 你可能希望通过新的 embed 指令将本地化资源嵌入到应用程序的可执行文件中。 导入 embed 包;如果未使用此包的任何导出标识符,可以使用空白导入 _ "embed"。 go import ( "embed" )
嵌入指令接受相对于包含该 Go 源文件目录的路径。我们甚至可以使用通配符嵌入多个文件,乃至整个文件夹。这需要创建一个 embed.FS 类型的变量,它实现了一个简单的虚拟文件系统。 go //go:embed embedded/locales/* var embeddedFS embed.FS
此时,我们应该使用 LoadFS 方法,而不是 Load 方法。 go err := app.I18n.LoadFS(embeddedFS, "./embedded/locales/*/*.ini", "en-US", "el-GR") // 或者按文件名加载所有语言: // app.I18n.LoadFS(embeddedFS, "./embedded/locales/*/*.ini") // 然后通过以下方式设置默认语言: // app.I18n.SetDefault("en-US")
定义翻译 本地化文件可以写成 YAML(推荐)、JSON、TOML 或 INI 格式。 每个文件都应包含键。键还可以拥有子键(我们称之为“节”)。 每个键的值形式应为字符串或映射,其中包含其翻译后的文本(或模板)以及/或复数形式的键值对。 Iris i18n 模块开箱即支持复数形式,详见下文。 Fmt 风格 yaml hi: "Hi %s!"
go ctx.Tr("Hi", "John") // 输出:Hi John!
模板 yaml hi: "Hi {{.Name}}!"
goctx.Tr("Hi", iris.Map{"Name": "John"}) // 输出: Hi John!x"
other
让我们创建一个支持复数功能的简单消息,它也可以复用上面创建的 Minutes 变量。
yaml
FreeDay:
"=3": "You have three days and %[2]d ${Minutes} off." # "FreeDay" 3, 15
one: "You have a day off." # "FreeDay", 1
other: "You have %[1]d free days." # "FreeDay", 5
1
2
3
4
go
ctx.Tr("FreeDay", 3, 15)
// 输出: You have three days and 15 minutes off.
ctx.Tr("FreeDay", 1)
// 输出: You have a day off.
ctx.Tr("FreeDay", 5)
// 输出: You have 5 free days.
1
2
3
4
5
6
让我们继续看一个稍微高级一点的例子,结合模板文本、函数、复数和变量。
yaml
Vars:
- Houses:
one: "house"
other: "houses"
- Gender:
"=1": "She"
"=2": "He"
VarTemplatePlural:
one: "${Gender} is awesome!"
other: "other (${Gender}) has %[3]d ${Houses}."
"=5": "{{call .InlineJoin .Names}} are awesome."
1
2
3
4
5
6
7
8
9
10
11
12
goconst (
female = iota + 1
male
)
ctx.Tr("VarTemplatePlural", iris.Map{
"PluralCount": 5,
"Names": []string{"John", "Peter"},
"InlineJoin": func(arr []string) string {
return strings.Join(arr, ", ")
},
})
// 输出:John, Peter are awesome
ctx.Tr("VarTemplatePlural", 1, female)
// 输出:She is awesome!
ctx.Tr("VarTemplatePlural", 2, female, 5)
// 输出:other (She) has 5 houses.
Sections(小节)
如果 key 不是保留字(比如 one、two 等),那它就会被当作一个小节(sub section)。小节之间用点号(.)分隔。
yaml
Welcome:
Message: "Welcome {{.Name}}"
go
ctx.Tr("Welcome.Message", iris.Map{"Name": "John"})
// 输出:Welcome John
Determining The Current Locale(确定当前 Locale)
可以通过 context.GetLocale 方法获取当前的 locale,或者判断 locale 是否为某个特定值:
go
func(ctx iris.Context) {
locale := ctx.GetLocale()
// [...]
}
Locale 接口的定义如下:
go
// Locale 是 `Localizer.GetLocale` 方法返回的接口。
// 它根据 "key" 或格式提供翻译,参见 `GetMessage`。
type Locale interface {
// Index 返回当前 locale 在语言列表中的索引。
Index() int
// Tag 返回该 Locale 绑定的完整语言 Tag,
// 不同 Locale 之间此值应保持唯一。
Tag() *language.Tag
// Language 返回用户在 `New` 函数中
// 提供的该 `Locale` 的确切语言代码。
//
// 等同于 `Tag().String()`,但它是静态的。
Language() string
// GetMessage 根据给定的 "key" 返回翻译后的文本。
GetMessage(key string, args ...interface{}) string
}
Retrieving Translation(获取翻译)
使用 context.Tr 方法可以快速获取本次请求对应的翻译文本:
go
func(ctx iris.Context) {
text := ctx.Tr("hi", "name")
// [...]
}
Inside Views(在视图中使用)
go
func(ctx iris.Context) {
ctx.View("index.html", iris.Map{
"tr": ctx.Tr,
})
}
应用的默认语言是第一个注册的语言。 go app := iris.New() // 第一个参数:Glob 文件路径模式 // 第二个可变参数:可选的语言标签, // 第一个即为默认/回退语言。 app.I18n.Load("./locales/*/*", "en-US", "el-GR", "zh-CN")
或者,如果按文件名加载所有语言: go app.I18n.Load("./locales/*/*") // 然后通过以下方式设置默认语言: app.I18n.SetDefault("en-US")
嵌入本地化资源 你可能希望通过新的 embed 指令将本地化资源嵌入到应用程序的可执行文件中。 导入 embed 包;如果未使用此包的任何导出标识符,可以使用空白导入 _ "embed"。 go import ( "embed" )
嵌入指令接受相对于包含该 Go 源文件目录的路径。我们甚至可以使用通配符嵌入多个文件,乃至整个文件夹。这需要创建一个 embed.FS 类型的变量,它实现了一个简单的虚拟文件系统。 go //go:embed embedded/locales/* var embeddedFS embed.FS
此时,我们应该使用 LoadFS 方法,而不是 Load 方法。 go err := app.I18n.LoadFS(embeddedFS, "./embedded/locales/*/*.ini", "en-US", "el-GR") // 或者按文件名加载所有语言: // app.I18n.LoadFS(embeddedFS, "./embedded/locales/*/*.ini") // 然后通过以下方式设置默认语言: // app.I18n.SetDefault("en-US")
定义翻译 本地化文件可以写成 YAML(推荐)、JSON、TOML 或 INI 格式。 每个文件都应包含键。键还可以拥有子键(我们称之为“节”)。 每个键的值形式应为字符串或映射,其中包含其翻译后的文本(或模板)以及/或复数形式的键值对。 Iris i18n 模块开箱即支持复数形式,详见下文。 Fmt 风格 yaml hi: "Hi %s!"
go ctx.Tr("Hi", "John") // 输出:Hi John!
模板 yaml hi: "Hi {{.Name}}!"
goctx.Tr("Hi", iris.Map{"Name": "John"}) // 输出: Hi John!