i18n

package
v1.0.41 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: MPL-2.0 Imports: 5 Imported by: 0

README

Lightweight Internationalization (i18n) Library

A simple, thread-safe internationalization library for Go that provides translation management with template support and pluralization.

Features

  • Singleton Pattern: Global instance for easy access across your application
  • Language Support: Uses golang.org/x/text/language.Tag for robust language handling
  • Template Support: Go templates for dynamic content injection
  • Pluralization: Automatic singular/plural form selection based on count
  • Thread-Safe: Safe for concurrent access
  • Minimal Dependencies: Only Go standard library + golang.org/x/text
  • Fallback Support: Automatic fallback to default language
  • Template Caching: Efficient template parsing and caching

Installation

go get github.com/c3p0-box/utils/i18n

Quick Start

package main

import (
    "fmt"
    "github.com/c3p0-box/utils/i18n"
    "golang.org/x/text/language"
)

func main() {
    // Set default language
    i18n.SetDefaultLanguage(language.English)

    // Add translations
    i18n.AddTranslation(language.English, "hello", "Hello", "")
    i18n.AddTranslation(language.Spanish, "hello", "Hola", "")

    // Translate
    fmt.Println(i18n.TranslateSimple(language.English, "hello")) // Output: Hello
    fmt.Println(i18n.TranslateSimple(language.Spanish, "hello")) // Output: Hola
}

API Reference

Core Functions
SetDefaultLanguage(lang language.Tag)

Sets the default fallback language.

AddTranslation(lang language.Tag, key, value, plural string) error

Adds a translation for the specified language and key.

  • lang: Language tag
  • key: Translation key
  • value: Singular form (can be a Go template)
  • plural: Plural form (optional, uses singular if empty)
AddTranslations(lang language.Tag, translations map[string]*Translation) error

Adds multiple translations for the specified language at once. More efficient than calling AddTranslation multiple times.

  • lang: Language tag
  • translations: Map where keys are translation keys and values are Translation structs
Translate(lang language.Tag, key string, count int, data interface{}) string

Retrieves and processes a translation with template data.

  • lang: Target language
  • key: Translation key
  • count: Determines singular (1) vs plural (≠1) form
  • data: Template data (can be nil)
TranslateSimple(lang language.Tag, key string) string

Simple translation without templates or count.

TranslatePlural(lang language.Tag, key string, count int) string

Translation with plural support but without template data.

Manager Instance Methods
GetInstance() *Manager

Returns the singleton manager instance.

(*Manager) GetAvailableLanguages() []language.Tag

Returns all languages that have translations.

(*Manager) GetTranslationKeys(lang language.Tag) []string

Returns all translation keys for a given language.

(*Manager) HasTranslation(lang language.Tag, key string) bool

Checks if a translation exists.

Usage Examples

Basic Translation
// Add simple translations
i18n.AddTranslation(language.English, "welcome", "Welcome!", "")
i18n.AddTranslation(language.French, "welcome", "Bienvenue!", "")

// Translate
msg := i18n.TranslateSimple(language.French, "welcome")
fmt.Println(msg) // Output: Bienvenue!
Template Usage
// Add translation with template
i18n.AddTranslation(language.English, "user_info", 
    "Hello {{.Name}}, you have {{.Messages}} message", 
    "Hello {{.Name}}, you have {{.Messages}} messages")

// Use with data
data := map[string]interface{}{
    "Name": "Alice",
    "Messages": 3,
}
msg := i18n.Translate(language.English, "user_info", 3, data)
fmt.Println(msg) // Output: Hello Alice, you have 3 messages
Pluralization
// Add translation with plural forms
i18n.AddTranslation(language.English, "file_count",
    "{{.Count}} file", "{{.Count}} files")

// Singular
data := map[string]interface{}{"Count": 1}
msg := i18n.Translate(language.English, "file_count", 1, data)
fmt.Println(msg) // Output: 1 file

// Plural
data = map[string]interface{}{"Count": 5}
msg = i18n.Translate(language.English, "file_count", 5, data)
fmt.Println(msg) // Output: 5 files
Bulk Translation Addition
// Create multiple translations at once
translations := map[string]*i18n.Translation{
    "hello": {Singular: "Hello", Plural: ""},
    "goodbye": {Singular: "Goodbye", Plural: ""},
    "item_count": {
        Singular: "{{.Count}} item", 
        Plural: "{{.Count}} items",
    },
}

// Add all translations for English at once
err := i18n.AddTranslations(language.English, translations)
if err != nil {
    log.Fatal(err)
}

// Use the translations
fmt.Println(i18n.TranslateSimple(language.English, "hello")) // Output: Hello
data := map[string]interface{}{"Count": 5}
fmt.Println(i18n.Translate(language.English, "item_count", 5, data)) // Output: 5 items
Fallback Behavior
// Set default language
i18n.SetDefaultLanguage(language.English)

// Add only English translation
i18n.AddTranslation(language.English, "error", "An error occurred", "")

// Request German translation - falls back to English
msg := i18n.TranslateSimple(language.German, "error")
fmt.Println(msg) // Output: An error occurred

// Request non-existing key - returns the key itself
msg = i18n.TranslateSimple(language.English, "non_existing")
fmt.Println(msg) // Output: non_existing
Working with Manager Instance
manager := i18n.GetInstance()

// Add translation using manager
manager.AddTranslation(language.Japanese, "thanks", "ありがとう", "")

// Check what languages are available
languages := manager.GetAvailableLanguages()
fmt.Printf("Available: %v\n", languages)

// Get all keys for a language
keys := manager.GetTranslationKeys(language.Japanese)
fmt.Printf("Japanese keys: %v\n", keys)

// Check if translation exists
exists := manager.HasTranslation(language.Japanese, "thanks")
fmt.Printf("Exists: %v\n", exists)

Migration from go-i18n/v2

If you're migrating from github.com/nicksnyder/go-i18n/v2, here are the key differences:

Old (go-i18n/v2):
bundle := i18n.NewBundle(language.English)
localizer := i18n.NewLocalizer(bundle, "en")
msg := localizer.Localize(&i18n.LocalizeConfig{
    MessageID: "welcome",
    TemplateData: map[string]interface{}{"Name": "Alice"},
})
New (this library):
i18n.SetDefaultLanguage(language.English)
i18n.AddTranslation(language.English, "welcome", "Welcome {{.Name}}", "")
msg := i18n.Translate(language.English, "welcome", 1, map[string]interface{}{"Name": "Alice"})

Thread Safety

This library is fully thread-safe. All operations use appropriate mutexes to ensure safe concurrent access.

Performance

  • Template Caching: Templates are parsed once and cached for reuse
  • Efficient Lookups: Fast map-based lookups for translations
  • Minimal Allocations: Optimized for low memory overhead

Limitations

  • Simple pluralization (singular/plural only, no complex plural rules)
  • No message loading from files (programmatic API only)
  • No ICU MessageFormat support (Go templates only)

License

This library is part of the c3p0-box/utils package and follows the same license terms.

Documentation

Overview

Package i18n provides a simple, thread-safe internationalization library for Go that supports translation management with template support and pluralization.

This package uses a singleton pattern with a global Manager instance for easy access across your application. It supports template-based message rendering, automatic fallback to default language, and thread-safe concurrent access.

Features:

  • Singleton Pattern: Global instance for easy access
  • Language Support: Uses golang.org/x/text/language.Tag for robust handling
  • Template Support: Go templates for dynamic content injection
  • Pluralization: Automatic singular/plural form selection based on count
  • Thread-Safe: Safe for concurrent access with appropriate mutexes
  • Minimal Dependencies: Only Go standard library + golang.org/x/text
  • Fallback Support: Automatic fallback to default language
  • Template Caching: Efficient template parsing and caching

Quick Start:

i18n.SetDefaultLanguage(language.English)
i18n.AddTranslation(language.English, "hello", "Hello, {{.Name}}!", "")
msg := i18n.Translate(language.English, "hello", 1, map[string]interface{}{"Name": "World"})

For more advanced usage, see the Manager type and its methods.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddTranslation

func AddTranslation(lang language.Tag, key, value, plural string) error

AddTranslation adds a translation to the global instance

func AddTranslations

func AddTranslations(lang language.Tag, translations map[string]*Translation) error

AddTranslations adds multiple translations to the global instance

func SetDefaultLanguage

func SetDefaultLanguage(lang language.Tag)

SetDefaultLanguage sets the default language for the global instance

func Translate

func Translate(lang language.Tag, key string, count int, data interface{}) string

Translate translates using the global instance

func TranslatePlural

func TranslatePlural(lang language.Tag, key string, count int) string

TranslatePlural translates with plural support using the global instance

func TranslateSimple

func TranslateSimple(lang language.Tag, key string) string

TranslateSimple translates using the global instance without templates

Types

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager is the singleton manager for all translations

func GetInstance

func GetInstance() *Manager

GetInstance returns the singleton instance of the translation manager

func (*Manager) AddTranslation

func (m *Manager) AddTranslation(lang language.Tag, key, value, plural string) error

AddTranslation adds a new translation for the specified language and key If plural is empty, the singular form will be used for plural as well

func (*Manager) AddTranslations

func (m *Manager) AddTranslations(lang language.Tag, translations map[string]*Translation) error

AddTranslations adds multiple translations for the specified language at once This is more efficient than calling AddTranslation multiple times as it only acquires the lock once translations is a map where keys are translation keys and values are Translation structs If a Translation's Plural field is empty, the Singular form will be used for plural as well

func (*Manager) GetAvailableLanguages

func (m *Manager) GetAvailableLanguages() []language.Tag

GetAvailableLanguages returns a list of all languages that have translations

func (*Manager) GetDefaultLanguage

func (m *Manager) GetDefaultLanguage() language.Tag

GetDefaultLanguage returns the current default language

func (*Manager) GetTranslationKeys

func (m *Manager) GetTranslationKeys(lang language.Tag) []string

GetTranslationKeys returns all translation keys for a given language

func (*Manager) HasTranslation

func (m *Manager) HasTranslation(lang language.Tag, key string) bool

HasTranslation checks if a translation exists for the given language and key

func (*Manager) SetDefaultLanguage

func (m *Manager) SetDefaultLanguage(lang language.Tag)

SetDefaultLanguage sets the default fallback language

func (*Manager) Translate

func (m *Manager) Translate(lang language.Tag, key string, count int, data interface{}) string

Translate retrieves and processes a translation for the given language and key count determines whether to use singular (count == 1) or plural (count != 1) form data is passed to the template for processing

func (*Manager) TranslatePlural

func (m *Manager) TranslatePlural(lang language.Tag, key string, count int) string

TranslatePlural is a convenience method for plural translations without templates

func (*Manager) TranslateSimple

func (m *Manager) TranslateSimple(lang language.Tag, key string) string

TranslateSimple is a convenience method for simple translations without templates

type Translation

type Translation struct {
	Singular string // Template string for singular form
	Plural   string // Template string for plural form (optional)
}

Translation represents a single translation entry with optional plural form

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL