Skip to main content

Go uluslararasılaştırmasına yönelik eksiksiz rehber

İleti dosyalarından goroutine açısından güvenli yerel ayar çözümlemeye kadar Go uygulamanızda go-i18n ile i18n'i kurun ve ardından çevirileri yapay zeka ile otomatikleştirin.

1

go-i18n'i kurun

go-i18n, Go için en popüler uluslararasılaştırma kitaplığıdır. CLDR çoğul kurallarını ve değişken değerlerini yerleştirmek için Go şablonlarını kullanır; JSON, TOML ve YAML ileti dosyalarını destekler. Dil etiketi eşleştirme için golang.org/x/text paketine de ihtiyacınız vardır.

go-i18n v2, Go 1.16+ gerektirir. golang.org/x/text paketi, go-i18n'in çoğul kuralı seçerken kendi içinde kullandığı BCP 47 dil etiketi ayrıştırma ve eşleştirme özelliklerini sağlar.
Terminal
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u golang.org/x/text/language
2

İleti dosyaları oluşturun

locales klasöründe her dil için bir JSON dosyası oluşturun. Her ileti bir kimlik ve bir veya daha fazla çoğul biçim içerir. Go-i18n, değişken değerlerini yerleştirmek için Go şablon söz dizimini (önünde nokta bulunan çift süslü parantezler) kullanır.

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."
  }
}
Noktalarla ayrılmış yollar yerine 'ItemCount' veya 'WelcomeBack' gibi açıklayıcı ileti kimlikleri kullanın. go-i18n iç içe anahtarları değil düz kimlikleri kullanır. Go kurallarıyla eşleşmesi için kimlikleri PascalCase biçiminde tutun.
3

Bundle'ı yükleyin

Bundle, go-i18n'in merkezi kayıt defteridir. Başlangıçta bir tane oluşturun, dosya biçiminizi kaydedin ve tüm ileti dosyalarını yükleyin. Bundle goroutine açısından güvenlidir; bir kez oluşturup uygulamanızın tamamında paylaşın.

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) // "こんにちは、世界!"
}
'message not found' iletisini görürseniz üç noktayı denetleyin: 1) İleti dosyası LoadMessageFile veya MustLoadMessageFile ile yüklenmiş mi? 2) Dosya uzantısı kayıtlı ayrıştırma işleviyle eşleşiyor mu? 3) LocalizeConfig içindeki MessageID, JSON dosyanızdaki anahtarla harf duyarlı biçimde tam olarak eşleşiyor mu?
4

Localizer'ı kullanın

Kullanıcının tercih ettiği dille her istek için bir Localizer oluşturun. Localizer, Bundle'daki iletileri çözümler, Go'nun text/template motoruyla şablon işlemeyi yönetir ve PluralCount değerine göre doğru çoğul biçimini seçer.

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 birden fazla dil dizesini kabul eder ve bunları sırayla dener. Accept-Language üst bilgisini doğrudan iletin: i18n.NewLocalizer(bundle, r.Header.Get("Accept-Language")). go-i18n üst bilgiyi ayrıştırır ve kullanılabilir çevirilerle otomatik olarak eşleştirir.
5

Çoğul kurallarını yönetin

go-i18n tüm diller için CLDR çoğul kurallarını uygular. İngilizcede 2 biçim (one, other), Arapçada 6 biçim (zero, one, two, few, many, other) ve Japoncada 1 biçim (other) vardır. İleti dosyalarınızda gerekli tüm biçimleri tanımlayın; go-i18n, PluralCount değerine göre doğru biçimi seçer.

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 ve TemplateData birbirinden ayrıdır. PluralCount çoğul biçimini seçer, TemplateData ise şablon işleme değerlerini sağlar. Sayının ileti metninde görünmesi gerekiyorsa her ikisinde de iletin: PluralCount: n ve TemplateData: map[string]interface{'}'{"Count": n}.
6

Yerel ayar algılama

Web uygulamalarında kullanıcının tercih ettiği dili sorgu parametreleri, çerezler, Accept-Language üst bilgisi veya URL yolu bölümleri gibi birden fazla kaynaktan algılayın. BCP 47 uyumlu dil uzlaşması için golang.org/x/text/language.Matcher kullanın.

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, ham kullanıcı tercihini değil desteklediğiniz diller arasındaki en iyi eşleşmeyi döndürür. Bir kullanıcı 'pt-BR' ister ve siz yalnızca 'pt' dilini desteklerseniz eşleştirici doğru biçimde 'pt' döndürür. Eşleştirici olmadan her bölgesel varyant için elle yedekleme mantığı yazmanız gerekir.
7

Anahtar başına yedeklemeyi go-locale-chain ile düzeltin

go-i18n'in bilinen bir sınırlaması vardır: bir yerel ayar eşleştiğinde (herhangi bir çevirisi yüklendiğinde) eksik anahtarlar zincirdeki sonraki yerel ayara geçmez. Kısmen çevrilmiş bir pt-BR dosyasına sahip pt-BR kullanıcısı, pt-PT veya pt'ye geçmek yerine boş dizeler görür. go-locale-chain, 75 yerleşik yerel ayar zincirinde anahtar başına yedekleme çözümlemesiyle bu sorunu düzeltir.

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, harici bağımlılığı olmayan açık kaynaklı bir Go paketidir. go-i18n'i tamamlar: ileti yükleme, çoğullaştırma ve şablon işleme için go-i18n'i; doğru yedekleme zinciri çözümlemesi için go-locale-chain'i kullanın.
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
Varsayılanları korurken belirli zincirleri özelleştirmek için ConfigureWithOverrides() kullanın. Örneğin pt-BR'yi yalnızca pt'ye geçecek biçimde basitleştirebilir veya varsayılanlarda bulunmayan sv-FI -> sv gibi bir yerel ayar zinciri ekleyebilirsiniz.
8

Çevirileri otomatikleştirin

i18n kurulumunuz tamamlandıktan sonra yerel ayar dosyalarınızı yapay zeka kullanarak çevirin. İngilizce kaynak dosyanızdan tüm hedef diller için doğrudan IDE'nizde veya CI/CD işlem hattınızda çeviriler oluşturun.

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
Aşamalı çeviri yapın: kaynak dosyanıza yeni ileti kimlikleri eklediğinizde tüm dosyaları yeniden oluşturmak yerine yalnızca yeni anahtarları çevirin. Böylece insanlar tarafından incelenmiş çeviriler korunur.

Çeviri kalitesini otomatikleştirin

Eksik anahtarları ve bozuk yer tutucuları kullanıma sunulmadan önce i18n-validate ile yakalayın. Gerçek çeviriler gelmeden önce kullanıcı arayüzünüzü i18n-pseudo ile sözde çeviriler kullanarak sınayın.

Yaygın hatalar

PluralCount ve TemplateData uyuşmazlığı

PluralCount çoğul biçimini seçer ancak değeri şablona eklemez. Sayının işlenen iletide görünmesi için değeri TemplateData içinde de iletmeniz gerekir. TemplateData olmadan '{'{.Count}'}' ifadesi '<no value>' olarak işlenir.

RegisterUnmarshalFunc işlevinin eksik olması

Dosya biçimi için bundle.RegisterUnmarshalFunc() çağrısını yapmayı unutursanız LoadMessageFile sessizce hiçbir ileti döndürmez. Dosyaları yüklemeden önce her zaman json.Unmarshal (veya toml/yaml) kaydını yapın.

Anahtar başına yedeklemenin çalışmaması

go-i18n'in NewLocalizer işlevi birden fazla dili kabul eder ancak bir yerel ayar tek bir anahtarla eşleştiğinde eksik anahtarlar yedek yerel ayara geçmek yerine boş dizeler döndürür. Bunu doğru anahtar başına zincirleme özelliğiyle düzeltmek için go-locale-chain kullanın.

Şablon söz dizimi: {'{.Var}'}, {'{Var}'} değil

go-i18n, Go's text/template söz dizimini kullanır. Değişkenlerin önünde nokta bulunmalıdır: {'{.Name}'}, {'{Name}'} değil. Nokta, TemplateData eşlemesine başvurur. Noktanın eksik olması şablon yürütme hatasına yol açar.

Önerilen dosya yapısı

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

i18n Agent'ı şimdi deneyin

Çeviri dosyanızı buraya bırakın

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

veya göz atmak için tıklayın

Hedef diller

Kayıt gerekmezAnında fiyat tahmini

go-locale-chain ile yerel ayar yedeklemesi

pt-BR gibi bölgesel bir yerel ayarda çeviri anahtarı eksik olduğunda go-i18n, önce üst yerel ayar pt'yi denetlemek yerine doğrudan varsayılan dile geçer.

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"},
    },
})

Desteklenen çerçevelerin ve 75 yerleşik zincirin tam listesi için Yerel Ayar Yedekleme Rehberimize bakın. Learn more →

Go i18n hakkında sık sorulan sorular