国际化称作 i18n,其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数。由于软件发行可能面向多个国家,对于不同国家的用户,软件显示不同语言的过程就是国际化。通常来讲,软件中的国际化是通过配置文件来实现的,假设要支撑两种语言,那么就需要两个版本的配置文件。
现在大部分的应用基本都是前后端分离架构,但是只要有需要后端渲染的功能,则后端依然会存在国际化的场景。
例如:下载 Excel,导出 PDF,发送邮件通知等。
这些场景中的通用语言可以使用 i18n 国际化的方式进行开发维护。
国际化的标准做法是每种语言模式定义一个通用语言的模板文件。
业务代码根据当前上下文中的语言模式,从对应的语言模版中提取通用语言对应的语种的表达。
在 Go 技术栈中,可以使用 /nicksnyder/go-i18n
这个框架,这个框架比较热门。
GitHub - nicksnyder/go-i18n: Translate your Go program into multiple languages.
https://github.com/nicksnyder/go-i18n
官方提供的例子中默认语种的数据是在代码里直接初始化的,实际上我们会将各个语种的数据都放在模版文件中。
以下就是基于官方 example 修改的一个这样的例子。
MessageID 这个属性很重要,通过这个属性定位到使用 toml 中哪个数据。
// Command example runs a sample webserver that uses go-i18n/v2/i18n.
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"strconv"
"github.com/BurntSushi/toml"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
var page = template.Must(template.New("").Parse(`
<!DOCTYPE html>
<html>
<body>
<h1>{{.Title}}</h1>
{{range .Paragraphs}}<p>{{.}}</p>{{end}}
</body>
</html>
`))
func main() {
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
// No need to load active.en.toml since we are providing default translations.
// bundle.MustLoadMessageFile("active.en.toml")
bundle.MustLoadMessageFile("./example/active.es.toml")
bundle.MustLoadMessageFile("./example/active.en.toml")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
lang := r.FormValue("lang")
if lang == "" {
lang = "en"
}
localizer := i18n.NewLocalizer(bundle, lang)
name := r.FormValue("name")
if name == "" {
name = "Bob"
}
unreadEmailCount, _ := strconv.ParseInt(r.FormValue("unreadEmailCount"), 10, 64)
helloPerson := localizer.MustLocalize(&i18n.LocalizeConfig{
DefaultMessage: &i18n.Message{
ID: "HelloPerson",
Other: "Hello {{.Name}}",
},
TemplateData: map[string]string{
"Name": name,
},
})
myUnreadEmails := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "MyUnreadEmails",
PluralCount: unreadEmailCount,
})
personUnreadEmails := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "PersonUnreadEmails",
PluralCount: unreadEmailCount,
TemplateData: map[string]interface{}{
"Name": name,
"UnreadEmailCount": unreadEmailCount,
},
})
err := page.Execute(w, map[string]interface{}{
"Title": helloPerson,
"Paragraphs": []string{
myUnreadEmails,
personUnreadEmails,
},
})
if err != nil {
panic(err)
}
})
fmt.Println("Listening on http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
[HelloPerson]
hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5"
other = "Hola {{.Name}}"
[MyUnreadEmails]
description = "The number of unread emails I have"
hash = "sha1-6a65d17f53981a3657db1897630e9cb069053ea8"
one = "Tengo {{.PluralCount}} correo electrónico sin leer"
other = "Tengo {{.PluralCount}} correos electrónicos no leídos"
[PersonUnreadEmails]
description = "The number of unread emails a person has"
hash = "sha1-3a672fa89c5c8564bb233c907638004983792464"
one = "{{.Name}} tiene {{.UnreadEmailCount}} correo electrónico no leído"
other = "{{.Name}} tiene {{.UnreadEmailCount}} correos electrónicos no leídos"
HelloPerson = "Hello {{.Name}}"
[MyUnreadEmails]
description = "The number of unread emails I have"
one = "I have {{.PluralCount}} unread email."
other = "I have {{.PluralCount}} unread emails."
[PersonUnreadEmails]
description = "The number of unread emails a person has"
one = "{{.Name}} has {{.UnreadEmailCount}} unread email."
other = "{{.Name}} has {{.UnreadEmailCount}} unread emails."
Then open http://localhost:8080 in your web browser.
You can customize the template data and locale via query parameters like this: http://localhost:8080/?name=Nick&unreadEmailCount=2 http://localhost:8080/?name=Nick&unreadEmailCount=2&lang=es
import (
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
func i18nExample() {
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.MustLoadMessageFile("./lang/active.zh.toml")
bundle.MustLoadMessageFile("./lang/active.en.toml")
localizer := i18n.NewLocalizer(bundle, "zh")
languageMode := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "LanguageMode",
})
fmt.Println(languageMode)
}
go.mod
module platform
go 1.18
require (
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/agiledragon/gomonkey/v2 v2.4.0
github.com/fatih/structs v1.1.0
github.com/fsnotify/fsnotify v1.4.9
github.com/gin-gonic/gin v1.7.7
github.com/golang/mock v1.5.0
github.com/google/uuid v1.3.0
github.com/hashicorp/go-retryablehttp v0.7.1
github.com/iancoleman/strcase v0.2.0
github.com/imroc/req v0.3.2
github.com/jinzhu/copier v0.3.4
github.com/json-iterator/go v1.1.12
github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/pelletier/go-toml v1.9.3
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.8.0
github.com/stretchr/testify v1.7.0
github.com/toolkits/net v0.0.0-20160910085801-3f39ab6fe3ce
gitlab.archeros.cn/Haihe/go-core v1.6.1
gitlab.archeros.cn/Haihe/haihe-sdk-go v1.7.1-0.20230821085944-1943b464f7d3
go.etcd.io/etcd/client/v3 v3.5.1
go.uber.org/automaxprocs v1.4.0
golang.org/x/sys v0.5.0
golang.org/x/text v0.15.0
gopkg.in/go-playground/validator.v9 v9.31.0
gorm.io/driver/mysql v1.3.2
gorm.io/gorm v1.23.1
)
active.zh.toml
[LanguageMode]
description = "语言模式"
other = "中文模式"
active.en.toml
[LanguageMode]
description = "语言模式"
other = "EnglishMode"
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有