golang支持.po/.mo文件的i18n国际化插件库t的使用
Golang 支持 .po/.mo 文件的 i18n 国际化插件库 t 的使用
介绍
t 是一个 Go 语言的国际化工具,灵感来自 GNU gettext,支持 .po 和 .mo 文件格式。
安装
go get -u github.com/youthlin/t
或者在 go.mod 中添加:
require (
github.com/youthlin/t latest
)
也可以使用 Gitee 镜像:
// go.mod:
replace github.com/youthlin/t latest => gitee.com/youthlin/gottext latest
使用示例
package main
import (
"fmt"
"github.com/youthlin/t"
)
func main() {
// 1. 绑定翻译文件
path := "path/to/filename.po" // 可以是 .po 或 .mo 文件
// 或者是一个目录
path = "path/to/po_mo/dir"
// (如果 mo 和 po 同名,po 会覆盖 mo 文件,因为 po 是文本文件更方便修改)
// 默认绑定到 default 域
t.Load(path)
// 或者指定文本域
t.Bind("my-domain", path)
// 2. 设置当前使用的文本域
t.SetDomain("my-domain")
// 3. 设置用户语言
// t.SetLocale("zh_CN")
t.SetLocale(t.MostMatchLocale()) // 空表示使用系统默认
// 4. 使用 gettext API
fmt.Println(t.T("Hello, world"))
fmt.Println(t.T("Hello, %v", "Tom"))
// 单复数处理
fmt.Println(t.N("One apple", "%d apples", 1)) // 输出: One apple
fmt.Println(t.N("One apple", "%d apples", 2)) // 输出: %d apples
// 支持格式化参数
fmt.Println(t.N("One apple", "%d apples", 2, 2)) // 输出: 2 apples
fmt.Println(t.N("%[2]s has one apple", "%[2]s has %[1]d apples", 2, 200, "Bob"))
// 输出: Bob has 200 apples
// 带上下文的翻译
t.X("msg_context_text", "msg_id")
t.XN("msg_context_text", "msg_id", "msg_plural", n)
}
API 说明
T(msgID, args...) // gettext
N(msgID, msgIDPlural, n, args...) // ngettext
X(msgCTxt, msgID, args...) // pgettext
XN(msgCTxt, msgID, msgIDPlural, n, args...) // npgettext
D(domain) // 指定文本域
L(locale) // 指定语言
文本域使用
t.Bind("domain1", "path1")
t.Bind("domain2", "path2")
t.SetLocale("zh_CN")
t.T("msg_id") // 使用 default 域
t.SetDomain("domain1")
t.T("msg_id") // 使用 domain1
t.D("domain2").T("msg_id") // 使用 domain2
t.D("unknown-domain").T("msg_id") // 直接返回 "msg_id"
语言选择
如果是 web 应用,可以为每个请求设置不同语言:
t.Load(path)
// 1. 直接指定语言
t.L("zh_CN").T("msg_id")
// 2. 根据用户偏好选择语言
// 2.1 获取服务器支持的语言
langs := t.Locales()
var supported []language.Tag
for _, lang = range langs {
supported = append(supported, language.Make(lang))
}
matcher := language.NewMatcher(supported)
// 2.2 获取用户接受的语言 (从浏览器头或cookie)
userAccept, _, _ := language.ParseAcceptLanguage("zh-CN,zh;q=0.9,en;q=0.8")
// 2.3 匹配最适合的语言
matchedTag, index, _ := matcher.Match(userAccept...)
userLang := langs[index]
t.L(userLang).T("msg_id")
// 同时指定文本域和语言
t.D(domain).L(userLang).T("msg_id")
提取翻译文本
使用 PoEdit 提取翻译文本:
# 在 PoEdit 中设置提取器:
# 语言: Go, 扩展名: *.go
# 提取命令: xgettext -C --add-comments=TRANSLATORS: --force-po -o %o %C %K %F
# 关键字设置: T:1;N:1,2;N64:1,2;X:2,1c;XN:2,3,1c;XN64:2,3,1c
xgettext -C --add-comments=TRANSLATORS: --force-po -kT -kN:1,2 -kX:2,1c -kXN:2,3,1c *.go
从 HTML 模板提取
安装提取工具:
go install github.com/youthlin/t/cmd/xtemplate@latest
已完成功能
- ✅ 支持 mo 二进制文件
- ✅ 从模板文件中提取文本
更多关于golang支持.po/.mo文件的i18n国际化插件库t的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang支持.po/.mo文件的i18n国际化插件库t的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 国际化(i18n)库推荐及使用指南
在Go语言中,有几个优秀的库可以处理.po/.mo文件的国际化(i18n)需求。下面我将介绍几个主流的选择,并提供详细的使用示例。
1. go-i18n (推荐)
go-i18n
是由Go官方团队维护的国际化库,支持.po/.mo文件格式。
安装
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u github.com/nicksnyder/go-i18n/v2/goi18n
基本使用
- 首先创建翻译文件,例如
active.en.toml
:
[hello]
other = "Hello, World!"
[greeting]
other = "Hello, {{.Name}}"
- 代码示例:
package main
import (
"fmt"
"log"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
func main() {
// 创建i18n Bundle
bundle := i18n.NewBundle(language.English)
// 加载翻译文件
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.MustLoadMessageFile("active.en.toml")
bundle.MustLoadMessageFile("active.zh.toml") // 中文翻译文件
// 创建本地化器
localizer := i18n.NewLocalizer(bundle, "zh") // 使用中文
// 简单翻译
helloMsg, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "hello",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(helloMsg) // 输出: 你好, 世界!
// 带参数的翻译
greetingMsg, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "greeting",
TemplateData: map[string]string{
"Name": "张三",
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(greetingMsg) // 输出: 你好, 张三
}
2. go-gettext
如果你需要直接处理.po/.mo文件,可以使用 go-gettext
库。
安装
go get github.com/leonelquinteros/gotext
使用示例
- 创建
locales/en_US/LC_MESSAGES/default.po
文件:
msgid "hello"
msgstr "Hello, World!"
msgid "greeting"
msgstr "Hello, %s"
- 编译为.mo文件:
msgfmt -o locales/en_US/LC_MESSAGES/default.mo locales/en_US/LC_MESSAGES/default.po
- 代码示例:
package main
import (
"fmt"
"github.com/leonelquinteros/gotext"
)
func main() {
// 配置语言环境
gotext.Configure("locales", "en_US", "default")
// 简单翻译
fmt.Println(gotext.Get("hello")) // 输出: Hello, World!
// 带参数的翻译
fmt.Println(gotext.Get("greeting", "John")) // 输出: Hello, John
}
3. 使用PO文件的最佳实践
- 组织翻译文件:
locales/
├── en_US/
│ └── LC_MESSAGES/
│ ├── default.po
│ └── default.mo
└── zh_CN/
└── LC_MESSAGES/
├── default.po
└── default.mo
- 自动重新加载 (开发环境):
// 使用gotext的自动重新加载功能
gotext.Configure("locales", "en_US", "default")
gotext.Get("hello") // 从磁盘加载
// 开发模式下可以设置自动重新加载
gotext.GetStorage().SetDomain("default")
gotext.GetStorage().SetLanguage("en_US")
- Web应用中的使用 (基于Gin框架示例):
func i18nMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
lang := c.GetHeader("Accept-Language")
if lang == "" {
lang = "en_US" // 默认语言
}
// 配置当前请求的语言
gotext.Configure("locales", lang, "default")
c.Next()
}
}
func main() {
r := gin.Default()
r.Use(i18nMiddleware())
r.GET("/hello", func(c *gin.Context) {
c.String(200, gotext.Get("hello"))
})
r.Run(":8080")
}
总结
- 对于大多数项目,推荐使用
go-i18n
,它功能全面且维护良好 - 如果需要直接处理.po/.mo文件,
go-gettext
是不错的选择 - 在Web应用中,可以通过中间件根据请求头动态切换语言
- 开发环境下可以启用自动重新加载翻译文件,方便调试
以上库都支持常见的国际化需求,如复数处理、变量插值等高级功能。根据项目需求选择合适的解决方案即可。