golang国际化文本本地化处理插件库go-i18n的使用
Golang国际化文本本地化处理插件库go-i18n的使用
go-i18n是一个Go包和命令行工具,可以帮助你将Go程序翻译成多种语言。
主要特性
- 支持Unicode通用语言环境数据存储库(CLDR)中200多种语言的复数形式字符串
- 支持使用text/template语法的带命名变量的字符串
- 支持任何格式的消息文件(如JSON、TOML、YAML)
安装
go get github.com/nicksnyder/go-i18n/v2/i18n
基本用法
创建Bundle
import (
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
// 创建Bundle用于应用程序生命周期
bundle := i18n.NewBundle(language.English)
加载翻译文件
// 注册TOML解析器
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
// 加载西班牙语翻译文件
bundle.LoadMessageFile("es.toml")
// 如果使用go:embed
//go:embed locale.*.toml
var LocaleFS embed.FS
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.LoadMessageFileFS(LocaleFS, "locale.es.toml")
创建Localizer
func(w http.ResponseWriter, r *http.Request) {
lang := r.FormValue("lang") // 从请求获取语言参数
accept := r.Header.Get("Accept-Language") // 获取Accept-Language头
localizer := i18n.NewLocalizer(bundle, lang, accept) // 创建本地化器
}
使用Localizer查找消息
localizer.Localize(&i18n.LocalizeConfig{
DefaultMessage: &i18n.Message{
ID: "PersonCats", // 消息ID
One: "{{.Name}} has {{.Count}} cat.", // 单数形式
Other: "{{.Name}} has {{.Count}} cats.", // 复数形式
},
TemplateData: map[string]interface{}{
"Name": "Nick", // 模板数据
"Count": 2,
},
PluralCount: 2, // 复数计数
}) // 输出: Nick has 2 cats.
命令行工具goi18n
安装命令行工具
go install -v github.com/nicksnyder/go-i18n/v2/goi18n@latest
goi18n -help
提取消息
使用goi18n extract
命令从Go源文件中提取所有i18n.Message结构体字面量到消息文件中。
示例active.en.toml文件:
# active.en.toml
[PersonCats]
description = "The number of cats a person has"
one = "{{.Name}} has {{.Count}} cat."
other = "{{.Name}} has {{.Count}} cats."
翻译新语言
- 创建空的消息文件(如translate.es.toml)
- 运行
goi18n merge active.en.toml translate.es.toml
填充待翻译消息 - 翻译完成后重命名为active.es.toml
- 加载翻译文件到bundle中
示例translate.es.toml文件:
# translate.es.toml
[HelloPerson]
hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5"
other = "Hello {{.Name}}"
翻译后的active.es.toml文件:
# active.es.toml
[HelloPerson]
hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5"
other = "Hola {{.Name}}"
翻译新消息
- 运行
goi18n extract
更新active.en.toml - 运行
goi18n merge active.*.toml
生成更新的translate.*.toml文件 - 翻译所有消息
- 运行
goi18n merge active.*.toml translate.*.toml
合并翻译
完整示例
package main
import (
"embed"
"fmt"
"github.com/BurntSushi/toml"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
"net/http"
)
//go:embed active.*.toml
var LocaleFS embed.FS
func main() {
// 创建Bundle
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
// 加载翻译文件
bundle.LoadMessageFileFS(LocaleFS, "active.es.toml")
// 模拟HTTP请求处理
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// 从请求获取语言参数
lang := r.FormValue("lang")
accept := r.Header.Get("Accept-Language")
// 创建Localizer
localizer := i18n.NewLocalizer(bundle, lang, accept)
// 本地化消息
message, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "HelloWorld",
})
if err != nil {
fmt.Fprintf(w, "Error: %v", err)
return
}
fmt.Fprintf(w, message)
})
http.ListenAndServe(":8080", nil)
}
active.en.toml文件:
[HelloWorld]
other = "Hello World"
active.es.toml文件:
[HelloWorld]
other = "Hola Mundo"
这个示例展示了如何使用go-i18n进行基本的国际化文本处理。你可以通过访问http://localhost:8080?lang=es
来测试西班牙语翻译。
更多关于golang国际化文本本地化处理插件库go-i18n的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang国际化文本本地化处理插件库go-i18n的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go-i18n 国际化文本本地化处理库使用指南
go-i18n 是一个强大的 Go 语言国际化(i18n)和本地化(l10n)库,它支持基于 JSON 或 TOML 格式的翻译文件,提供了灵活的文本本地化功能。下面我将详细介绍如何使用这个库。
安装
go get github.com/nicksnyder/go-i18n/v2/i18n
基本使用
1. 创建翻译文件
首先创建翻译文件,通常放在 locales
目录下:
locales/en-US.json
:
{
"hello_world": "Hello World",
"emails": {
"welcome": {
"subject": "Welcome to our service",
"body": "Hello {{.Name}}, thank you for joining us on {{.Date}}"
}
}
}
locales/zh-CN.json
:
{
"hello_world": "你好世界",
"emails": {
"welcome": {
"subject": "欢迎使用我们的服务",
"body": "你好 {{.Name}},感谢你在 {{.Date}} 加入我们"
}
}
}
2. 初始化 i18n Bundle
package main
import (
"fmt"
"log"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
func main() {
// 创建新的 Bundle
bundle := i18n.NewBundle(language.English)
// 注册 JSON 解码器
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
// 加载翻译文件
bundle.MustLoadMessageFile("locales/en-US.json")
bundle.MustLoadMessageFile("locales/zh-CN.json")
// 创建本地化器
localizer := i18n.NewLocalizer(bundle, "zh-CN")
// 获取简单翻译
helloMsg, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "hello_world",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(helloMsg) // 输出: 你好世界
// 获取带参数的翻译
emailBody, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "emails.welcome.body",
TemplateData: map[string]interface{}{
"Name": "张三",
"Date": "2023-05-20",
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(emailBody) // 输出: 你好 张三,感谢你在 2023-05-20 加入我们
}
高级功能
1. 复数处理
locales/en-US.json
:
{
"unread_notification_count": {
"one": "You have {{.Count}} unread notification",
"other": "You have {{.Count}} unread notifications"
}
}
locales/zh-CN.json
:
{
"unread_notification_count": "您有 {{.Count}} 条未读通知"
}
使用代码:
count := 5
msg, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "unread_notification_count",
PluralCount: count,
TemplateData: map[string]interface{}{
"Count": count,
},
})
// en-US: "You have 5 unread notifications"
// zh-CN: "您有 5 条未读通知"
2. 默认消息
msg, err := localizer.Localize(&i18n.LocalizeConfig{
DefaultMessage: &i18n.Message{
ID: "greeting",
Other: "Hello, {{.Name}}!",
},
TemplateData: map[string]interface{}{
"Name": "John",
},
})
3. 多语言切换
func getLocalizer(lang string) *i18n.Localizer {
// 在实际应用中,你可能需要从请求头或cookie中获取语言偏好
return i18n.NewLocalizer(bundle, lang)
}
func handler(w http.ResponseWriter, r *http.Request) {
lang := r.URL.Query().Get("lang") // 从URL参数获取语言
if lang == "" {
lang = "en-US" // 默认语言
}
localizer := getLocalizer(lang)
// 使用localizer进行本地化...
}
最佳实践
- 组织翻译文件:按功能模块组织翻译内容,而不是全部放在一个文件中
- 命名规范:使用点分隔的命名方式,如
module.component.message
- 参数验证:在模板中使用参数前进行验证
- 错误处理:总是检查
Localize
返回的错误 - 性能优化:在应用启动时加载所有翻译文件,而不是每次请求时加载
完整示例
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
var bundle *i18n.Bundle
func initI18n() {
bundle = i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
bundle.MustLoadMessageFile("locales/en-US.json")
bundle.MustLoadMessageFile("locales/zh-CN.json")
bundle.MustLoadMessageFile("locales/ja-JP.json")
}
func main() {
initI18n()
http.HandleFunc("/greet", greetHandler)
log.Println("Server started on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func greetHandler(w http.ResponseWriter, r *http.Request) {
lang := r.URL.Query().Get("lang")
if lang == "" {
lang = "en-US"
}
localizer := i18n.NewLocalizer(bundle, lang)
name := r.URL.Query().Get("name")
if name == "" {
name = "Guest"
}
greeting, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "greeting.message",
DefaultMessage: &i18n.Message{
ID: "greeting.message",
Other: "Hello, {{.Name}}!",
},
TemplateData: map[string]interface{}{
"Name": name,
},
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, greeting)
}
总结
go-i18n 提供了强大的国际化支持,包括:
- 多语言翻译文件支持
- 模板变量替换
- 复数处理
- 默认消息回退
- 灵活的本地化配置
通过合理组织翻译文件和正确使用 Localizer,你可以轻松地为 Go 应用程序添加国际化支持。记得根据实际需求选择合适的语言标识符(如 zh-CN、en-US 等)并保持一致。