进阶 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!

复数形式

Iris 的 i18n 支持复数变量。要定义针对不同语言的变量,必须定义一个新的 Vars 键段。变量可用的键为: one"=x"(其中 x 为数字) "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, }) }

评论 (0)