Skip to main content

Täielik Go internatsionaliseerimise juhend

Sõnumifailidest goroutine-ohutu lokaadilahenduseni: seadista Go rakenduses i18n go-i18n-iga ja automatiseeri seejärel tõlked tehisintellektiga.

1

Paigalda go-i18n

go-i18n on Go populaarseim internatsionaliseerimisteek. See kasutab CLDR-i mitmusereegleid, Go malle muutujate interpoleerimiseks ning toetab JSON-, TOML- ja YAML-sõnumifaile. Keelemärgendite sobitamiseks vajad ka paketti golang.org/x/text.

go-i18n v2 nõuab Go versiooni 1.16+. Pakett golang.org/x/text pakub BCP 47 keelemärgendite parsimist ja sobitamist, mida go-i18n kasutab sisemiselt mitmusereegli valimiseks.
Terminal
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u golang.org/x/text/language
2

Loo sõnumifailid

Loo kataloogi locales üks JSON-fail keele kohta. Igal sõnumil on ID ja üks või mitu mitmusevormi. Go-i18n kasutab muutujate interpoleerimiseks Go malli süntaksit ehk topeltlooksulge koos punkti eesliitega.

locales/en.json
{
  "HelloWorld": { "other": "Hello, World!" },
  "Greeting": { "other": "Hello, {{.Name}}!" },
  "ItemCount": {
    "one": "{{.Count}} item",
    "other": "{{.Count}} items"
  },
  "WelcomeBack": {
    "other": "Welcome back, {{.Name}}. You have {{.Count}} messages."
  }
}
Kasuta punktidega eraldatud radade asemel kirjeldavaid sõnumi-ID-sid, nagu 'ItemCount' või 'WelcomeBack'. go-i18n kasutab lamedaid ID-sid, mitte pesastatud võtmeid. Hoia ID-d Go tava järgi PascalCase'is.
3

Laadi Bundle

Bundle on go-i18n-i keskregister. Loo see käivitamisel üks kord, registreeri failivorming ja laadi kõik sõnumifailid. Bundle on goroutine-ohutu — loo see üks kord ja jaga kogu rakenduses.

main.go
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) // "こんにちは、世界!"
}
Kui näed tõrget 'message not found', kontrolli kolme asja: 1) Sõnumifail laaditi funktsiooniga LoadMessageFile või MustLoadMessageFile. 2) Faililaiend vastab registreeritud lahtipakkimisfunktsioonile. 3) LocalizeConfigi MessageID vastab JSON-faili võtmele täpselt ja tõstutundlikult.
4

Kasuta Localizerit

Loo iga päringu jaoks kasutaja eelistatud keelega Localizer. Localizer lahendab sõnumid Bundle'ist, töötleb mallide renderdamist Go text/template-mootoriga ning valib PluralCounti põhjal õige mitmusevormi.

Using the Localizer
// 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,
    },
})
HTTP handler with locale detection
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))
}
NewLocalizer võtab vastu mitu keelestringi ja proovib neid järjekorras. Edasta Accept-Language'i päis otse: i18n.NewLocalizer(bundle, r.Header.Get("Accept-Language")). go-i18n parsib päise ja sobitab selle automaatselt saadaolevate tõlgetega.
5

Töötle mitmusereegleid

go-i18n rakendab CLDR-i mitmusereeglid kõigile keeltele. Inglise keeles on kaks vormi (one, other), araabia keeles kuus (zero, one, two, few, many, other) ja jaapani keeles üks (other). Määra sõnumifailides kõik vajalikud vormid ning go-i18n valib PluralCounti põhjal õige.

Plural forms by language
// 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}}個のアイテム"
  }
}
Using plural rules
// 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: "عنصر واحد"
PluralCount ja TemplateData on eraldi. PluralCount valib mitmusevormi ja TemplateData annab väärtused malli renderdamiseks. Kui vajad kogust sõnumitekstis, edasta see mõlemas: PluralCount: n ja TemplateData: map[string]interface{'}'{"Count": n}.
6

Lokaadi tuvastamine

Veebirakendustes tuvasta kasutaja eelistatud keel mitmest allikast: päringuparameetritest, küpsistest, Accept-Language'i päisest või URL-i tee segmentidest. BCP 47 nõuetele vastavaks keeleläbirääkimiseks kasuta golang.org/x/text/language.Matcherit.

Locale detection middleware
// 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
})
language.NewMatcher tagastab toetatud keelte seast parima vaste, mitte kasutaja töötlemata eelistuse. Kui kasutaja taotleb pt-BR-i ja toetad ainult pt-d, tagastab matcher õigesti pt. Ilma matcherita vajaksid iga piirkondliku variandi jaoks käsitsi varuloogikat.
7

Paranda võtmekohane varulokaat go-locale-chain'iga

go-i18n-il on teadaolev piirang: kui lokaat sobib ehk selle tõlked on osaliselt laaditud, ei liigu puuduvad võtmed ahela järgmisele lokaadile. Osaliselt tõlgitud pt-BR-failiga pt-BR kasutaja saab pt-PT-le või pt-le taandumise asemel tühjad stringid. go-locale-chain parandab selle võtmekohase varulokaadi lahendamisega 75 sisseehitatud lokaadiahelas.

Terminal
go get github.com/i18n-agent/go-locale-chain
go-locale-chain with go-i18n
package 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
}
go-locale-chain on avatud lähtekoodiga Go pakett, millel pole väliseid sõltuvusi. See täiendab go-i18n-i — kasuta go-i18n-i sõnumite laadimiseks, mitmusevormideks ja mallide renderdamiseks ning go-locale-chain'i õigeks varulokaadiahela lahendamiseks.
Standalone usage (no go-i18n)
// 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 locale
Kasuta ConfigureWithOverrides(), et kohandada kindlaid ahelaid ja säilitada vaikeväärtused. Näiteks lihtsusta pt-BR taanduma ainult pt-le või lisa vaikeväärtustest puuduva lokaadi ahel, nagu sv-FI → sv.
8

Automatiseeri tõlked

Kui i18n-i seadistus on valmis, tõlgi lokaadifailid tehisintellektiga. Loo ingliskeelsest lähtefailist tõlked kõigile sihtkeeltele otse IDE-s või CI/CD-konveieris.

Terminal
# 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,es
Tõlgi järk-järgult — kui lisad lähtefaili uusi sõnumi-ID-sid, tõlgi kõigi failide uuesti loomise asemel ainult uued võtmed. Nii säilivad inimeste ülevaadatud tõlked.

Automatiseeri tõlkekvaliteet

Leia i18n-validate'i abil puuduvad võtmed ja katkised kohatäitjad enne avaldamist. Testi kasutajaliidest i18n-pseudo abil pseudotõlgetega enne päris tõlgete saabumist.

Levinud komistuskivid

PluralCount ja TemplateData ei ühti

PluralCount valib mitmusevormi, kuid ei sisesta väärtust malli. Kogus tuleb edastada ka TemplateDatas, et see ilmuks renderdatud sõnumisse. Ilma TemplateDatata renderdub '{'{.Count}'}' kujul '<no value>'.

RegisterUnmarshalFunc puudub

LoadMessageFile ei tagasta märkamatult ühtegi sõnumit, kui unustad failivormingu jaoks bundle.RegisterUnmarshalFunc() kutsuda. Registreeri enne failide laadimist alati json.Unmarshal või toml/yaml.

Võtmekohane varulokaat ei tööta

go-i18n-i NewLocalizer võtab vastu mitu keelt, kuid kui lokaat sobib ühe võtmega, tagastavad puuduvad võtmed taandumise asemel tühjad stringid. Paranda see go-locale-chain'iga, mis pakub õiget võtmekohast kaskaadi.

Mallisüntaks: {'{.Var}'}, mitte {'{Var}'}

go-i18n kasutab Go text/template-süntaksit. Muutujatel peab olema punkti eesliide: {'{.Name}'}, mitte {'{Name}'}. Punkt viitab TemplateData kaardile. Puuduv punkt põhjustab malli käitustõrke.

Soovituslik failistruktuur

Project Structure
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.sum

Proovi i18n Agent'i kohe

Kukuta tõlkefail siia

JSON, YAML, PO, XML, CSV, Markdown, Properties

või klõpsa faili valimiseks

Sihtkeeled

Registreerumine pole vajalikKohene hinnang

Varulokaat go-locale-chain'iga

Kui piirkondlikust lokaadist, näiteks pt-BR-st, puudub tõlkevõti, liigub go-i18n otse vaikekeelele ega kontrolli esmalt põhilokaati pt.

Terminal
go get github.com/i18n-agent/go-locale-chain
Configuration
import 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"},
    },
})

Vaata meie varulokaadi juhendist kõigi toetatud raamistike ja 75 sisseehitatud ahela loendit. Learn more →

Go i18n-i KKK