Pilnīgs Go internacionalizācijas ceļvedis
No ziņojumu failiem līdz gorutīnu drošai lokalizācijas atrisināšanai: iestatiet i18n Go lietotnē ar go-i18n, pēc tam automatizējiet tulkošanu ar MI.
Instalēt go-i18n
go-i18n ir populārākā Go internacionalizācijas bibliotēka. Tā izmanto CLDR daudzskaitļa kārtulas, Go veidnes mainīgo interpolācijai un atbalsta JSON, TOML un YAML ziņojumu failus. Valodas tagu saskaņošanai vajadzīgs arī golang.org/x/text.
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u golang.org/x/text/languageIzveidot ziņojumu failus
Izveidojiet vienu JSON failu katrai valodai direktorijā locales. Katram ziņojumam ir ID un viena vai vairākas daudzskaitļa formas. Mainīgo interpolācijai go-i18n izmanto Go veidņu sintaksi (dubultas figūriekavas ar punkta prefiksu).
{
"HelloWorld": { "other": "Hello, World!" },
"Greeting": { "other": "Hello, {{.Name}}!" },
"ItemCount": {
"one": "{{.Count}} item",
"other": "{{.Count}} items"
},
"WelcomeBack": {
"other": "Welcome back, {{.Name}}. You have {{.Count}} messages."
}
}Ielādēt komplektu
Bundle ir go-i18n centrālais reģistrs. Palaišanas laikā izveidojiet vienu komplektu, reģistrējiet failu formātu un ielādējiet visus ziņojumu failus. Bundle ir gorutīnu drošs — izveidojiet to vienreiz un kopīgojiet visā lietotnē.
package main
import (
"encoding/json"
"fmt"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
func main() {
// 1. Create a bundle with a default language
bundle := i18n.NewBundle(language.English)
// 2. Register the unmarshal function for your file format
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
// 3. Load message files
bundle.MustLoadMessageFile("locales/en.json")
bundle.MustLoadMessageFile("locales/ja.json")
bundle.MustLoadMessageFile("locales/de.json")
// 4. Create a localizer and localize a message
localizer := i18n.NewLocalizer(bundle, "ja")
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "HelloWorld",
})
fmt.Println(msg) // "こんにちは、世界!"
}Izmantot Localizer
Katram pieprasījumam izveidojiet Localizer ar lietotāja vēlamo valodu. Localizer atrisina ziņojumus no Bundle, apstrādā veidņu atveidi ar Go text/template dzinēju un pēc PluralCount izvēlas pareizo daudzskaitļa formu.
// Simple message
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "HelloWorld",
})
// Message with template data
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "Greeting",
TemplateData: map[string]interface{}{
"Name": "Alice",
},
})
// "Hello, Alice!" (en) or "こんにちは、Aliceさん!" (ja)
// Plural + template data
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "ItemCount",
PluralCount: 5,
TemplateData: map[string]interface{}{
"Count": 5,
},
})
// "5 items" (en) or "5個のアイテム" (ja)
// Combined: plurals + multiple variables
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "WelcomeBack",
TemplateData: map[string]interface{}{
"Name": "Alice",
"Count": 3,
},
})func handler(w http.ResponseWriter, r *http.Request) {
// Accept-Language: ja,en;q=0.9,de;q=0.8
accept := r.Header.Get("Accept-Language")
// NewLocalizer accepts multiple languages — first match wins
localizer := i18n.NewLocalizer(bundle, accept)
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "HelloWorld",
})
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Write([]byte(msg))
}Apstrādāt daudzskaitļa kārtulas
go-i18n ievieš CLDR daudzskaitļa kārtulas visām valodām. Angļu valodā ir 2 formas (one, other), arābu — 6 (zero, one, two, few, many, other), japāņu — 1 (other). Ziņojumu failos definējiet visas vajadzīgās formas, un go-i18n izvēlēsies pareizo pēc PluralCount.
// English: 2 forms (one, other)
{
"ItemCount": {
"one": "{{.Count}} item",
"other": "{{.Count}} items"
}
}
// Arabic: 6 forms (zero, one, two, few, many, other)
{
"ItemCount": {
"zero": "لا عناصر",
"one": "عنصر واحد",
"two": "عنصران",
"few": "{{.Count}} عناصر",
"many": "{{.Count}} عنصرًا",
"other": "{{.Count}} عنصر"
}
}
// Japanese: 1 form (other)
{
"ItemCount": {
"other": "{{.Count}}個のアイテム"
}
}// go-i18n selects the correct plural form based on PluralCount
localizer := i18n.NewLocalizer(bundle, "ar")
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "ItemCount",
PluralCount: 3,
TemplateData: map[string]interface{}{
"Count": 3,
},
})
// Arabic "few" form: "3 عناصر"
msg = localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "ItemCount",
PluralCount: 1,
TemplateData: map[string]interface{}{
"Count": 1,
},
})
// Arabic "one" form: "عنصر واحد"Lokalizācijas noteikšana
Tīmekļa lietotnēs nosakiet lietotāja vēlamo valodu no vairākiem avotiem: vaicājuma parametriem, sīkfailiem, galvenes Accept-Language vai URL ceļa segmentiem. BCP 47 atbilstošai valodas saskaņošanai izmantojiet golang.org/x/text/language.Matcher.
// detectLocale resolves the user's preferred language.
// Priority: query param > cookie > Accept-Language header > default
func detectLocale(r *http.Request, matcher language.Matcher) string {
// 1. Explicit query parameter: ?lang=ja
if lang := r.URL.Query().Get("lang"); lang != "" {
tag, _, _ := matcher.Match(language.Make(lang))
return tag.String()
}
// 2. Cookie from previous selection
if cookie, err := r.Cookie("lang"); err == nil {
tag, _, _ := matcher.Match(language.Make(cookie.Value))
return tag.String()
}
// 3. Accept-Language header
accept := r.Header.Get("Accept-Language")
if accept != "" {
tags, _, _ := language.ParseAcceptLanguage(accept)
if len(tags) > 0 {
tag, _, _ := matcher.Match(tags...)
return tag.String()
}
}
return "en" // 4. Default
}
// Usage:
matcher := language.NewMatcher([]language.Tag{
language.English, language.Japanese,
language.German, language.Spanish,
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
locale := detectLocale(r, matcher)
localizer := i18n.NewLocalizer(bundle, locale)
// ... use localizer
})Izlabot katras atslēgas atkāpšanos ar go-locale-chain
go-i18n ir zināms ierobežojums: tiklīdz lokalizācija atbilst (ir ielādēti kaut daži tās tulkojumi), trūkstošās atslēgas nepāriet uz nākamo lokalizāciju ķēdē. pt-BR lietotājs ar daļēji tulkotu pt-BR failu saņem tukšas virknes, nevis atkāpjas uz pt-PT vai pt. go-locale-chain to novērš ar katras atslēgas atkāpšanās atrisināšanu 75 iebūvētās lokalizāciju ķēdēs.
go get github.com/i18n-agent/go-locale-chainpackage main
import (
"encoding/json"
"fmt"
"github.com/nicksnyder/go-i18n/v2/i18n"
localechain "github.com/i18n-agent/go-locale-chain"
"golang.org/x/text/language"
)
func main() {
// 1. Configure fallback chains (call once at startup)
localechain.Configure()
// 2. Set up go-i18n bundle as usual
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
bundle.MustLoadMessageFile("locales/en.json")
bundle.MustLoadMessageFile("locales/pt.json")
bundle.MustLoadMessageFile("locales/pt-PT.json")
bundle.MustLoadMessageFile("locales/pt-BR.json")
// 3. Resolve with per-key fallback
result, _ := localechain.ResolveWithLoader("pt-BR", func(locale string) (map[string]string, error) {
localizer := i18n.NewLocalizer(bundle, locale)
messages := make(map[string]string)
for _, id := range []string{"hello", "goodbye", "thanks"} {
msg, err := localizer.Localize(&i18n.LocalizeConfig{MessageID: id})
if err == nil {
messages[id] = msg
}
}
return messages, nil
})
fmt.Println(result["hello"]) // "Olá (BR)" — from pt-BR
fmt.Println(result["goodbye"]) // "Adeus (PT)" — fallback to pt-PT
fmt.Println(result["thanks"]) // "Obrigado" — fallback to pt
}// Standalone: zero external dependencies, works with any format
localechain.Configure()
result, _ := localechain.ResolveWithLoader("es-MX", func(locale string) (map[string]string, error) {
data, err := os.ReadFile(fmt.Sprintf("locales/%s.json", locale))
if err != nil {
return nil, err // Locale file doesn't exist — skip
}
var msgs map[string]string
json.Unmarshal(data, &msgs)
return msgs, nil
})
// es-MX -> es-419 -> es: each key resolved from most specific localeAutomatizēt tulkošanu
Kad i18n iestatīšana ir pabeigta, tulkojiet lokalizācijas failus ar MI. Ģenerējiet visu mērķa valodu tulkojumus no angļu avota faila tieši IDE vai CI/CD konveijerā.
# In your IDE, ask your AI assistant:
> Translate locales/en.json to German, Japanese, and Spanish
✓ locales/de.json created (1.2s)
✓ locales/ja.json created (1.5s)
✓ locales/es.json created (1.1s)
# Or use the CLI in CI/CD:
npx i18n-agent translate locales/en.json --lang de,ja,esAutomatizēt tulkojumu kvalitāti
Biežākās kļūdas
PluralCount un TemplateData neatbilstība
Trūkst RegisterUnmarshalFunc
Katras atslēgas atkāpšanās nedarbojas
Veidnes sintakse: {'{.Var}'}, nevis {'{Var}'}
Ieteicamā failu struktūra
my-go-app/
├── locales/
│ ├── en.json # Source language (English)
│ ├── de.json # German translations
│ ├── ja.json # Japanese translations
│ ├── es.json # Spanish translations
│ ├── pt.json # Portuguese (base)
│ ├── pt-PT.json # Portuguese (Portugal)
│ └── pt-BR.json # Portuguese (Brazil)
├── i18n/
│ ├── bundle.go # Bundle initialization
│ ├── detect.go # Locale detection logic
│ └── middleware.go # HTTP middleware for locale
├── main.go
├── go.mod
└── go.sumIzmēģiniet i18n Agent tūlīt
Nometiet tulkošanas failu šeit
JSON, YAML, PO, XML, CSV, Markdown, Properties
vai noklikšķiniet, lai izvēlētos
Mērķa valodas
Lokalizācijas atkāpšanās ar go-locale-chain
Ja reģionālajā lokalizācijā, piemēram, pt-BR, trūkst tulkojuma atslēgas, go-i18n uzreiz pāriet uz noklusējuma valodu, nevis vispirms pārbauda vecāklokalizāciju pt.
go get github.com/i18n-agent/go-locale-chainimport localechain "github.com/i18n-agent/go-locale-chain"
chain := localechain.New(localechain.Config{
Fallbacks: map[string][]string{
"pt-BR": {"pt", "en"},
"zh-Hant-HK": {"zh-Hant", "zh", "en"},
},
})Pilnu atbalstīto sistēmu sarakstu un 75 iebūvētās ķēdes skatiet mūsu lokalizāciju atkāpšanās ceļvedī. Learn more →