i18n

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Mar 21, 2026 License: MIT Imports: 23 Imported by: 11

README

go-i18n

Internationalization library for Go applications.

Overview

go-i18n provides translation management through a simple Translate(locale, key, args...) API. It supports multiple translation file formats, locale fallback chains, custom formatters, and integration with Go templates.

Installation

go get github.com/goliatone/go-i18n

Core Concepts

Store

The Store interface provides read only access to translation templates indexed by locale and key. The package includes StaticStore, an immutable in-memory implementation.

Loader

The Loader interface retrieves translations from external sources. FileLoader supports JSON and YAML files. Multiple files can be loaded and merged.

Translator

The Translator interface exposes a single method: Translate(locale, key string, args ...any) (string, error). The SimpleTranslator implementation handles locale fallback and template formatting.

Formatter

The Formatter interface formats translation templates with arguments. Default implementation uses fmt.Sprintf. Custom formatters can be injected via configuration.

FallbackResolver

The FallbackResolver interface returns fallback locale chains. When a translation is missing in the requested locale, the translator checks each fallback in order.

Shared Locale Policy

go-i18n now exposes a shared locale-policy surface for callers that need canonical locale handling outside the translator.

Core helpers:

  • NormalizeLocale(locale)
  • NormalizeLocales(locales)
  • NormalizeAndSortLocales(locales)
  • LocaleParent(locale)
  • LocaleParentChain(locale)

Catalog helpers:

  • LocaleCatalog.Match(locale) resolves a requested locale against the configured catalog using exact-or-parent matching across all locales.
  • LocaleCatalog.MatchAcceptLanguage(header) resolves an Accept-Language header across all configured locales as the convenience selection helper.
  • LocaleCatalog.MatchAcceptLanguageWithOptions(header, MatchOptions) exposes explicit scoped selection such as active-only Accept-Language matching.
  • LocaleCatalog.DecodeMetadata(locale, out) decodes generic locale metadata into a caller-owned struct.

Resolution helper:

  • ResolveLocale(locale, ResolveLocaleOptions) builds a deterministic locale chain for routing, cache keys, and request planning.

Conservative defaults matter here:

  • Match and default MatchAcceptLanguage are convenience selection helpers, not full policy engines.
  • They consider all configured locales by default, including inactive ones.
  • Use MatchAcceptLanguageWithOptions(..., MatchOptions{Scope: ScopeActiveOnly}) when request binding should reject inactive locales.
  • ResolveLocale defaults to exact matching.
  • It does not expand parents unless ExpandParents is set.
  • It does not expand fallbacks unless ExpandFallbacks is set.
  • It does not append the default locale unless IncludeDefault is set.

That public API is intentionally narrower than translator lookup. SimpleTranslator still uses its runtime lookup order for translation retrieval, but that behavior is not the default shared locale-policy contract for other consumers.

normalized := i18n.NormalizeLocale(" ES_mx ")
locales := i18n.NormalizeLocales([]string{"es_mx", "es", "ES-MX"})

catalog := cfg.LocaleCatalog()
routed, _ := catalog.Match("es-MX")
browser, _ := catalog.MatchAcceptLanguage("es-MX,es;q=0.9,en;q=0.8")
admin, _ := catalog.MatchAcceptLanguageWithOptions("fr-CA,fr;q=0.9,en;q=0.8", i18n.MatchOptions{
    Scope: i18n.ScopeActiveOnly,
})

resolution := i18n.ResolveLocale("es-MX", i18n.ResolveLocaleOptions{
    Catalog:       catalog,
    Resolver:      cfg.Resolver,
    MatchStrategy: i18n.MatchExact,
    ExpandParents: true,
})

_ = routed
_ = browser
_ = admin

Basic Usage

// Load translations from files
loader := i18n.NewFileLoader(
    "locales/en.json",
    "locales/es.json",
)

// Build configuration
cfg, err := i18n.NewConfig(
    i18n.WithLocales("en", "es"),
    i18n.WithDefaultLocale("en"),
    i18n.WithLoader(loader),
    i18n.WithFallback("es", "en"),
)
if err != nil {
    return err
}

// Create translator
translator, err := cfg.BuildTranslator()
if err != nil {
    return err
}

// Translate messages
msg, err := translator.Translate("es", "home.greeting", "Alice")
if err != nil {
    return err
}

Translation Files

JSON Format
{
  "en": {
    "home.title": "Welcome",
    "home.greeting": "Hello %s"
  },
  "es": {
    "home.title": "Bienvenido",
    "home.greeting": "Hola %s"
  }
}
YAML Format
en:
  home.title: Welcome
  home.greeting: Hello %s
es:
  home.title: Bienvenido
  home.greeting: Hola %s

Template Integration

The package provides helpers for Go templates including translation and formatting functions.

registry := i18n.NewFormatterRegistry()

helpers := i18n.TemplateHelpers(translator, i18n.HelperConfig{
    TemplateHelperKey: "t",
    Registry:          registry,
    OnMissing: func(locale, key string, args []any, err error) string {
        return fmt.Sprintf("[missing:%s]", key)
    },
})

tmpl := template.New("page").Funcs(helpers)

Template usage:

{{t .Locale "home.greeting" .Name}}
{{format_date .Locale .Timestamp}}
{{format_currency .Locale .Amount "USD"}}
Formatter Registry & Default Locales
  • NewFormatterRegistry eagerly registers locale-aware providers for English (en) and Spanish (es) using golang.org/x/text and CLDR bundle data.
  • The registry shares the same fallback resolver as the translator; regional locales such as es-MX automatically fall back to their parent (es) when a dedicated provider is missing.
  • Formatter func maps are memoised per locale. Any call to Register, RegisterLocale, RegisterProvider, or RegisterTypedProvider invalidates the cache so new helpers become visible immediately.
  • Template helpers wrap each formatter, defaulting to the registry’s primary locale when templates omit a locale argument. Advanced templates can access formatter_funcs to inspect the resolved helper map directly.
Generating Locale Bundles

Locale-specific CLDR bundles are generated via the helper in cmd/i18n-formatters.

  1. Install the CLDR archive (taskfile cldr:install) and export CLDR_CORE_DIR.
  2. Run the generator with the full Go toolchain path:
    /Users/goliatone/.g/go/bin/go run ./cmd/i18n-formatters \
      -locale=en -locale=es -locale=el \
      -cldr "${CLDR_CORE_DIR}" \
      -out formatters_cldr_data.go
    
  3. Check the generated file into version control so builds remain deterministic.
  4. Add the new locale to WithFormatterLocales(...) (or WithLocales(...)) so the registry ensures provider coverage during configuration.

Built-in Formatters

The package includes locale-aware formatters for common use cases. Defaults are sourced from CLDR snapshots bundled in formatters_cldr_data.go and golang.org/x/text primitives.

  • FormatDate(locale, time) - Date formatting
  • FormatDateTime(locale, time) - DateTime formatting
  • FormatTime(locale, time) - Time formatting
  • FormatCurrency(locale, amount, currency) - Currency formatting
  • FormatNumber(locale, value, decimals) - Number formatting
  • FormatPercent(locale, value, decimals) - Percentage formatting
  • FormatOrdinal(locale, value) - Ordinal number formatting
  • FormatList(locale, items) - List formatting with commas and conjunctions
  • FormatMeasurement(locale, value, unit) - Measurement formatting
  • FormatPhone(locale, raw) - Phone metadata formatting

Custom formatters can be registered per locale:

registry := i18n.NewFormatterRegistry()
registry.Register("format_currency", func(locale string, value float64, currency string) string {
    if locale == "es" && currency == "EUR" {
        return fmt.Sprintf("%.2f EUR", value)
    }
    return i18n.FormatCurrency(locale, value, currency)
})
Phone Dial Plans & Libphonenumber Adapter
  • The registry ships curated dial plans for high-traffic locales (en, es) so format_phone formats inputs into +<country> <groups> without extra setup.
  • Register additional metadata-driven plans with i18n.RegisterPhoneDialPlan(locale, i18n.PhoneDialPlan{ ... }), or provide a fully custom formatter via i18n.RegisterPhoneFormatter.
  • Query built-in coverage using i18n.DefaultPhoneDialPlan(locale) when you need to introspect the bundled configuration.

Optional libphonenumber integration lives in modules/libphonenumber with its own go.mod. Consumers opt-in explicitly:

import libphone "github.com/goliatone/go-i18n/modules/libphonenumber"

func init() {
    libphone.RegisterMany([]string{"en-US", "es", "fr"})
    // Or specialise behaviour:
    libphone.Register("mx", libphone.WithRegion("MX"))
}

The adapter pulls github.com/nyaruka/phonenumbers, offering Google’s phone parsing and formatting while keeping the core module lean.

Translation Hooks

Hooks allow interception of translation calls for logging, metrics, or debugging:

cfg, err := i18n.NewConfig(
    i18n.WithTranslatorHooks(i18n.TranslationHookFuncs{
        Before: func(ctx *i18n.TranslatorHookContext) {
            // Called before translation lookup
        },
        After: func(ctx *i18n.TranslatorHookContext) {
            // Called after translation lookup
            // ctx.Result and ctx.Error available
        },
    }),
)

Culture Data & Formatting Rules

Applications can provide locale-specific business data and formatting rules through a single JSON file. The library includes embedded defaults for common locales (en, es, el) and automatically merges application-provided data.

Culture Data File Format
{
  "currency_codes": {
    "en": "USD",
    "es": "EUR",
    "ar": "AED"
  },
  "support_numbers": {
    "en": "+1 555 010 4242",
    "es": "+34 900 123 456"
  },
  "lists": {
    "trending_products": {
      "en": ["coffee", "tea", "cake"],
      "es": ["café", "té", "pastel"]
    }
  },
  "measurement_preferences": {
    "default": {
      "weight": {"unit": "kg"}
    },
    "en": {
      "weight": {
        "unit": "lb",
        "conversion_from": {"kg": 2.20462}
      }
    }
  },
  "formatting_rules": {
    "ar": {
      "locale": "ar",
      "date_patterns": {
        "pattern": "{day}/{month}/{year}",
        "day_first": true,
        "month_style": "number"
      },
      "currency_rules": {
        "pattern": "{amount} {symbol}",
        "symbol_position": "after",
        "decimal_separator": ".",
        "thousand_separator": ",",
        "decimals": 2
      },
      "month_names": [
        "يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو",
        "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"
      ],
      "time_format": {
        "use_24_hour": false,
        "pattern": "3:04 PM"
      }
    }
  }
}
Using Culture Data
cfg, err := i18n.NewConfig(
    i18n.WithLocales("en", "es", "ar"),
    i18n.WithCultureData("locales/culture_data.json"),
)

// Access culture service
cultureService := cfg.CultureService()
currencyCode, _ := cultureService.GetCurrencyCode("ar")
supportNumber, _ := cultureService.GetSupportNumber("es")
products, _ := cultureService.GetList("en", "trending_products")

// Access in templates
helpers := cfg.TemplateHelpers(translator, i18n.HelperConfig{
    LocaleKey: "Locale",
})
// Available helpers: currency_code, support_number, list, measurement_pref
Culture Data Features
  • Embedded Defaults: Library includes formatting rules for en, es, el
  • Application Override: Provide custom rules that merge with or override defaults
  • Locale Fallback: Uses same fallback chain as translations (e.g., ar-SA → ar → en)
  • Per-Locale Overrides: Use WithCultureOverride(locale, path) for locale-specific files
Formatting Rules

The formatting_rules section allows applications to customize how dates, times, currencies, and numbers are formatted for each locale:

  • date_patterns: Date format patterns with placeholders {day}, {month}, {year}
  • currency_rules: Currency symbol placement and separators
  • month_names: Localized month names
  • time_format: 12/24-hour clock preference

Custom formatting rules automatically integrate with the formatter registry and are used by format_date, format_time, format_currency template helpers.

Configuration Options

  • WithDefaultLocale(locale) - Set default locale
  • WithLocales(...locales) - Register supported locales
  • WithLoader(loader) - Set translation loader
  • WithStore(store) - Set custom store implementation
  • WithFallbackResolver(resolver) - Set custom fallback resolver
  • WithFallback(locale, ...fallbacks) - Configure fallback chain for a locale
  • WithFormatter(formatter) - Set custom formatter
  • WithFormatterLocales(...locales) - Configure formatter provider coverage and fallback scaffolding
  • WithFormatterProvider(locale, provider) - Inject custom formatter providers per locale
  • WithTranslatorHooks(...hooks) - Add translation hooks
  • WithCultureData(path) - Load culture data and formatting rules from JSON file
  • WithCultureOverride(locale, path) - Add locale-specific culture data override

See docs/locale_policy_v1.md for locale-policy migration notes and release details, and docs/locale_policy_compatibility_report.md for the final compatibility sweep and follow-on adoption notes.

Error Handling

The package defines standard errors:

  • ErrMissingTranslation - Translation not found in any locale including fallbacks
  • ErrNotImplemented - Feature not implemented

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrMissingTranslation = errors.New("i18n: missing translation")

ErrMissingTranslation indicates that no translation was found for locale/key.

View Source
var ErrNotImplemented = errors.New("i18n: not implemented")

ErrNotImplemented marks APIs that are intentionally stubbed during bootstrapping.

Functions

func CultureHelpers added in v0.2.0

func CultureHelpers(service CultureService, localeKey string) map[string]any

CultureHelpers returns template helper functions for culture data

func FormatCurrency

func FormatCurrency(locale string, amount float64, currency string) string

func FormatDate

func FormatDate(locale string, t time.Time) string

func FormatDateTime

func FormatDateTime(locale string, t time.Time) string

func FormatList

func FormatList(locale string, items []string) string

func FormatMeasurement

func FormatMeasurement(locale string, value float64, unit string) string

func FormatNumber

func FormatNumber(locale string, value float64, decimals int) string

func FormatOrdinal

func FormatOrdinal(locale string, value int) string

func FormatPercent

func FormatPercent(locale string, value float64, decimals int) string

func FormatPhone

func FormatPhone(locale, raw string) string

func FormatTime

func FormatTime(locale string, t time.Time) string

func GeneratedCLDRLocales added in v0.2.0

func GeneratedCLDRLocales() []string

func LocaleParent added in v0.3.0

func LocaleParent(locale string) string

LocaleParent returns the closest parent locale, if any.

func LocaleParentChain added in v0.3.0

func LocaleParentChain(locale string) []string

LocaleParentChain returns the parent locale chain from nearest parent to root.

func NormalizeAndSortLocales added in v0.3.0

func NormalizeAndSortLocales(locales []string) []string

NormalizeAndSortLocales canonicalizes, deduplicates, and sorts deterministically.

func NormalizeLocale added in v0.3.0

func NormalizeLocale(locale string) string

NormalizeLocale canonicalizes a locale identifier for shared use across the package.

func NormalizeLocales added in v0.3.0

func NormalizeLocales(locales []string) []string

NormalizeLocales canonicalizes, deduplicates, and preserves first-seen order.

func RegisterCLDRFormatters added in v0.2.0

func RegisterCLDRFormatters(registry *FormatterRegistry, locales ...string)

RegisterCLDRFormatters wires locale-specific helpers sourced from CLDR bundles.

func RegisterGeneratedCLDRFormatters added in v0.2.0

func RegisterGeneratedCLDRFormatters(registry *FormatterRegistry)

func RegisterPhoneDialPlan added in v0.2.0

func RegisterPhoneDialPlan(locale string, plan PhoneDialPlan)

RegisterPhoneDialPlan registers a dial plan for a locale using the shared formatter pipeline. The plan is converted into a formatter that formats numbers in the +<country> groups... pattern.

func RegisterPhoneFormatter added in v0.2.0

func RegisterPhoneFormatter(locale string, formatter PhoneFormatterFunc)

RegisterPhoneFormatter registers a custom phone formatter for the given locale. The formatter receives the resolved locale and raw input string.

func RegisterXTextFormatters

func RegisterXTextFormatters(registry *FormatterRegistry, rulesProvider *FormattingRulesProvider, locales ...string)

RegisterXTextFormatters registers locale aware formatters backed by golang.org/x/text

func TemplateHelpers

func TemplateHelpers(t Translator, cfg HelperConfig) map[string]any

TemplateHelpers exposes translator + formatter helpers for go-template.

For production use, supply a properly configured Registry via HelperConfig.Registry or use Config.TemplateHelpers() which automatically configures fallback resolution for regional locale variants (e.g., es-MX → es → en).

When cfg.Registry is nil, this function creates a minimal registry with automatic parent-chain fallback resolution (e.g., zh-Hant-HK → zh-Hant → zh).

Types

type Config

type Config struct {
	DefaultLocale string
	Locales       []string
	Loader        Loader
	Store         Store
	Resolver      FallbackResolver
	Formatter     Formatter
	Hooks         []TranslationHook
	// contains filtered or unexported fields
}

Config captures translator and formatter setup

func NewConfig

func NewConfig(opts ...Option) (*Config, error)

NewConfig builds Config via supplied options

func (*Config) BuildTranslator

func (cfg *Config) BuildTranslator() (Translator, error)

func (*Config) CultureService added in v0.2.0

func (cfg *Config) CultureService() CultureService

CultureService returns the culture service

func (*Config) FormatterRegistry added in v0.2.0

func (cfg *Config) FormatterRegistry() *FormatterRegistry

func (*Config) LocaleCatalog added in v0.2.0

func (cfg *Config) LocaleCatalog() *LocaleCatalog

LocaleCatalog exposes the immutable locale metadata snapshot loaded from culture data.

func (*Config) TemplateHelpers added in v0.2.0

func (cfg *Config) TemplateHelpers(t Translator, helperCfg HelperConfig) map[string]any

type CultureData added in v0.2.0

type CultureData struct {
	SchemaVersion          string                              `json:"schema_version"`
	DefaultLocale          string                              `json:"default_locale"`
	Locales                map[string]LocaleDefinition         `json:"locales"`
	Currencies             map[string]CurrencyInfo             `json:"currencies"`
	SupportNumbers         map[string]string                   `json:"support_numbers"`
	Lists                  map[string]map[string][]string      `json:"lists"`
	MeasurementPreferences map[string]MeasurementPreferenceSet `json:"measurement_preferences"`
	FormattingRules        map[string]FormattingRules          `json:"formatting_rules"`
}

CultureData contains locale-specific business/cultural information

type CultureDataLoader added in v0.2.0

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

CultureDataLoader loads culture data from various sources

func NewCultureDataLoader added in v0.2.0

func NewCultureDataLoader(defaultPath string) *CultureDataLoader

NewCultureDataLoader creates a loader

func (*CultureDataLoader) AddOverride added in v0.2.0

func (l *CultureDataLoader) AddOverride(locale, path string)

AddOverride adds a locale-specific override file

func (*CultureDataLoader) Load added in v0.2.0

func (l *CultureDataLoader) Load() (*CultureData, error)

Load reads culture data from JSON files

type CultureService added in v0.2.0

type CultureService interface {
	// GetCurrencyCode returns the currency code for a locale
	GetCurrencyCode(locale string) (string, error)

	// GetCurrency returns currency metadata for a locale
	GetCurrency(locale string) (CurrencyInfo, error)

	// GetSupportNumber returns the support contact for a locale
	GetSupportNumber(locale string) (string, error)

	// GetList returns a locale-specific list by name
	GetList(locale, name string) ([]string, error)

	// GetMeasurementPreference returns preferred units for a locale
	GetMeasurementPreference(locale, measurementType string) (*UnitPreference, error)

	// ConvertMeasurement converts a value to the preferred unit for a locale
	ConvertMeasurement(locale string, value float64, fromUnit, measurementType string) (float64, string, string, error)
}

CultureService provides access to cultural/business data

func NewCultureService added in v0.2.0

func NewCultureService(data *CultureData, resolver FallbackResolver) CultureService

NewCultureService creates a culture service from data

type CurrencyFormatRules added in v0.2.0

type CurrencyFormatRules struct {
	// Pattern: {symbol}, {amount}
	Pattern        string `json:"pattern"`
	SymbolPosition string `json:"symbol_position"` // "before", "after"
	DecimalSep     string `json:"decimal_separator"`
	ThousandSep    string `json:"thousand_separator"`
	Decimals       int    `json:"decimals"`
}

CurrencyFormatRules defines currency formatting

type CurrencyInfo added in v0.2.0

type CurrencyInfo struct {
	Code   string `json:"code"`
	Symbol string `json:"symbol"`
}

CurrencyInfo describes currency metadata for a locale.

type DatePatternRules added in v0.2.0

type DatePatternRules struct {
	// Pattern uses placeholders: {day}, {month}, {year}
	Pattern    string `json:"pattern"`
	DayFirst   bool   `json:"day_first"`
	MonthStyle string `json:"month_style"` // "name", "number", "short"
}

DatePatternRules defines how dates are formatted

type FallbackResolver

type FallbackResolver interface {
	Resolve(locale string) []string
}

FallbackResolver resolves fallback locale chains

type FileLoader

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

func NewFileLoader

func NewFileLoader(paths ...string) *FileLoader

func (*FileLoader) Load

func (l *FileLoader) Load() (Translations, error)

func (*FileLoader) WithPluralRuleFiles added in v0.2.0

func (l *FileLoader) WithPluralRuleFiles(paths ...string) *FileLoader

func (*FileLoader) WithPluralRules added in v0.2.0

func (l *FileLoader) WithPluralRules(paths ...string) Loader

WithPluralRules satisfies the pluralRuleLoader contract used by config wiring.

type Formatter

type Formatter interface {
	Format(template string, args ...any) (string, error)
}

Formatter formats a template string with positional arguments

type FormatterCapabilities added in v0.2.0

type FormatterCapabilities struct {
	Number      bool
	Currency    bool
	Date        bool
	DateTime    bool
	Time        bool
	List        bool
	Ordinal     bool
	Measurement bool
	Phone       bool
}

type FormatterFunc

type FormatterFunc func(string, ...any) (string, error)

FormatterFunc adapts plain functions into Formatter

func (FormatterFunc) Format

func (fn FormatterFunc) Format(template string, args ...any) (string, error)

Format impelements Fromatter for FormatterFunc

type FormatterProvider

type FormatterProvider func(locale string) map[string]any

type FormatterRegistry

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

FormatRegistry manages formatter functions and locale specific overrides

func NewFormatterRegistry

func NewFormatterRegistry(opts ...FormatterRegistryOption) *FormatterRegistry

NewFormatterRegistry seeds a registry with default formatter implementations

func (*FormatterRegistry) Formatter

func (r *FormatterRegistry) Formatter(name, locale string) (any, bool)

Formatter returns the helper implementation for the given name and locale

func (*FormatterRegistry) FuncMap

func (r *FormatterRegistry) FuncMap(locale string) map[string]any

FUncMap returns all helper functions applicable to the locale

func (*FormatterRegistry) Register

func (r *FormatterRegistry) Register(name string, fn any)

Register sets or replaces a default ipmlementtion for <name> helper

func (*FormatterRegistry) RegisterLocale

func (r *FormatterRegistry) RegisterLocale(locale, name string, fn any)

RegisterLocale registers a locale specific ovveride for the <name> helper

func (*FormatterRegistry) RegisterProvider

func (r *FormatterRegistry) RegisterProvider(locale string, provider FormatterProvider)

func (*FormatterRegistry) RegisterTypedProvider added in v0.2.0

func (r *FormatterRegistry) RegisterTypedProvider(locale string, provider TypedFormatterProvider)

type FormatterRegistryOption added in v0.2.0

type FormatterRegistryOption func(*formatterRegistryConfig)

func WithFormatterRegistryLocales added in v0.2.0

func WithFormatterRegistryLocales(locales ...string) FormatterRegistryOption

func WithFormatterRegistryProvider added in v0.2.0

func WithFormatterRegistryProvider(locale string, provider FormatterProvider) FormatterRegistryOption

func WithFormatterRegistryResolver added in v0.2.0

func WithFormatterRegistryResolver(resolver FallbackResolver) FormatterRegistryOption

func WithFormatterRegistryTypedProvider added in v0.2.0

func WithFormatterRegistryTypedProvider(locale string, provider TypedFormatterProvider) FormatterRegistryOption

func WithFormattingRulesProvider added in v0.2.0

func WithFormattingRulesProvider(provider *FormattingRulesProvider) FormatterRegistryOption

type FormattingDataLoader added in v0.2.0

type FormattingDataLoader interface {
	Load(locale string) (*FormattingRules, error)
	Available() []string
}

FormattingDataLoader loads formatting rules from embedded data

type FormattingRules added in v0.2.0

type FormattingRules struct {
	Locale        string              `json:"locale"`
	DatePatterns  DatePatternRules    `json:"date_patterns"`
	CurrencyRules CurrencyFormatRules `json:"currency_rules"`
	MonthNames    []string            `json:"month_names"`
	TimeFormat    TimeFormatRules     `json:"time_format"`
}

FormattingRules contains all locale-specific formatting patterns

type FormattingRulesProvider added in v0.2.0

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

FormattingRulesProvider provides formatting rules for locales

func NewFormattingRulesProvider added in v0.2.0

func NewFormattingRulesProvider(cultureData *CultureData, resolver FallbackResolver) *FormattingRulesProvider

NewFormattingRulesProvider creates a provider from culture data

func (*FormattingRulesProvider) Get added in v0.2.0

Get loads formatting rules for a locale It tries exact match, then base language, then falls back to English

type HelperConfig

type HelperConfig struct {
	// LocaleKey selects the context key used to infer locale from template data.
	LocaleKey string
	// Registry allows callers to supply a custom formatter registry.
	Registry *FormatterRegistry
	// OnMissing controls the string returned when a translation is missing.
	OnMissing MissingTranslationHandler
	// TemplateHelperKey customizes the translator helper name (defaults to "translate").
	TemplateHelperKey string
}

HelperConfig configures template helper exports

type HookedTranslator

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

func (*HookedTranslator) DefaultLocale added in v0.2.0

func (t *HookedTranslator) DefaultLocale() string

func (*HookedTranslator) Translate

func (t *HookedTranslator) Translate(locale, key string, args ...any) (string, error)

type Loader

type Loader interface {
	Load() (Translations, error)
}

Loader retrieves the translations used to seed a Store

type LoaderFunc

type LoaderFunc func() (Translations, error)

LoaderFunc adapters allow bare functions to implement Loader interface

func (LoaderFunc) Load

func (fn LoaderFunc) Load() (Translations, error)

Load implements Loader for LoaderFunc

type Locale

type Locale struct {
	Code   string
	Name   string
	Parent string
}

Locale metadata placeholder pending richer implementation

type LocaleCatalog added in v0.2.0

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

LocaleCatalog is an immutable snapshot of locale metadata loaded from culture data.

func NewLocaleCatalogFromLocales added in v0.4.0

func NewLocaleCatalogFromLocales(defaultLocale string, locales []string) (*LocaleCatalog, error)

NewLocaleCatalogFromLocales builds a catalog from an explicit locale set and marks each supplied locale active. This is useful for request-bound matching against a caller-owned active locale list.

func (*LocaleCatalog) ActiveLocaleCodes added in v0.2.0

func (c *LocaleCatalog) ActiveLocaleCodes() []string

ActiveLocaleCodes returns all locales marked active, sorted alphabetically.

func (*LocaleCatalog) AllLocaleCodes added in v0.2.0

func (c *LocaleCatalog) AllLocaleCodes() []string

AllLocaleCodes returns every locale in the catalog, sorted alphabetically.

func (*LocaleCatalog) DecodeMetadata added in v0.3.0

func (c *LocaleCatalog) DecodeMetadata(locale string, out any) error

DecodeMetadata decodes locale metadata into a caller-owned output struct.

func (*LocaleCatalog) DefaultLocale added in v0.2.0

func (c *LocaleCatalog) DefaultLocale() string

DefaultLocale returns the configured default locale.

func (*LocaleCatalog) DisplayName added in v0.2.0

func (c *LocaleCatalog) DisplayName(locale string) string

DisplayName returns the human-friendly name for the requested locale.

func (*LocaleCatalog) Fallbacks added in v0.2.0

func (c *LocaleCatalog) Fallbacks(locale string) []string

Fallbacks returns the configured fallback chain for the locale.

func (*LocaleCatalog) Has added in v0.2.0

func (c *LocaleCatalog) Has(locale string) bool

Has reports whether the locale exists in the catalog.

func (*LocaleCatalog) IsActive added in v0.2.0

func (c *LocaleCatalog) IsActive(locale string) bool

IsActive reports whether the locale is marked active.

func (*LocaleCatalog) Locale added in v0.2.0

func (c *LocaleCatalog) Locale(locale string) (LocaleMetadata, bool)

Locale returns the full metadata payload for a locale.

func (*LocaleCatalog) Match added in v0.3.0

func (c *LocaleCatalog) Match(locale string) (LocaleMetadata, bool)

Match resolves a requested locale to a supported catalog locale. The default public behavior is exact-or-parent matching across all locales.

func (*LocaleCatalog) MatchAcceptLanguage added in v0.3.0

func (c *LocaleCatalog) MatchAcceptLanguage(header string) (LocaleMetadata, bool)

MatchAcceptLanguage resolves an Accept-Language header to the best supported locale across all configured locales.

func (*LocaleCatalog) MatchAcceptLanguageWithOptions added in v0.3.0

func (c *LocaleCatalog) MatchAcceptLanguageWithOptions(header string, opts MatchOptions) (LocaleMetadata, bool)

MatchAcceptLanguageWithOptions resolves an Accept-Language header to the best supported locale using explicit matching scope controls.

func (*LocaleCatalog) Metadata added in v0.2.0

func (c *LocaleCatalog) Metadata(locale string) map[string]any

Metadata returns a shallow copy of the custom metadata map for the locale.

type LocaleDefinition added in v0.2.0

type LocaleDefinition struct {
	DisplayName string         `json:"display_name"`
	Active      *bool          `json:"active,omitempty"`
	Fallbacks   []string       `json:"fallbacks,omitempty"`
	Metadata    map[string]any `json:"metadata,omitempty"`
}

LocaleDefinition represents the raw locale metadata as defined in culture data files.

type LocaleMetadata added in v0.2.0

type LocaleMetadata struct {
	Code        string
	DisplayName string
	Active      bool
	Fallbacks   []string
	Metadata    map[string]any
}

LocaleMetadata exposes the immutable metadata for a single locale.

type LocaleResolution added in v0.3.0

type LocaleResolution struct {
	Requested string
	Canonical string
	Matched   string
	Parents   []string
	Fallbacks []string
	Default   string
	Chain     []string
}

LocaleResolution describes the requested locale, any supported match, and the final ordered chain.

func ResolveLocale added in v0.3.0

func ResolveLocale(locale string, opts ResolveLocaleOptions) LocaleResolution

ResolveLocale builds an explicit, deterministic locale chain.

type LocaleScope added in v0.3.0

type LocaleScope int

LocaleScope controls whether matching considers all locales or only active locales.

const (
	ScopeAll LocaleScope = iota
	ScopeActiveOnly
)

type MatchOptions added in v0.3.0

type MatchOptions struct {
	Scope LocaleScope
}

MatchOptions configures scoped supported-locale selection helpers.

type MatchStrategy added in v0.3.0

type MatchStrategy int

MatchStrategy controls how a requested locale is mapped to a supported locale.

const (
	MatchExact MatchStrategy = iota
	MatchExactOrParent
	MatchBestFit
)

type MeasurementPreferenceSet added in v0.2.0

type MeasurementPreferenceSet map[string]UnitPreference

MeasurementPreferenceSet groups unit preferences by measurement type.

type Message added in v0.2.0

type Message struct {
	MessageMetadata
	Variants map[PluralCategory]MessageVariant
}

func (Message) Clone added in v0.2.0

func (m Message) Clone() Message

func (Message) Content added in v0.2.0

func (m Message) Content() string

func (*Message) SetContent added in v0.2.0

func (m *Message) SetContent(content string)

func (*Message) SetVariant added in v0.2.0

func (m *Message) SetVariant(category PluralCategory, vairant MessageVariant)

func (Message) Variant added in v0.2.0

func (m Message) Variant(category PluralCategory) (MessageVariant, bool)

type MessageMetadata added in v0.2.0

type MessageMetadata struct {
	ID          string
	Domain      string
	Locale      string
	Description string
}

type MessageVariant added in v0.2.0

type MessageVariant struct {
	Template   string
	FormatArgs []string
	UsesCount  bool
	Source     string
	Checksum   string
}

type MissingTranslationHandler

type MissingTranslationHandler func(locale, key string, args []any, err error) string

MissingTranslationHandler decides what string should be emitted when Translator.Translate returns an error

type Option

type Option func(*Config) error

Option mutates Config during construction

func EnablePluralFallbackSeeding added in v0.2.0

func EnablePluralFallbackSeeding() Option

EnablePluralFallbackSeeding opts into automatic fallback chain seeding when pluralization is enabled.

func EnablePluralization added in v0.2.0

func EnablePluralization(rulePaths ...string) Option

EnablePluralization wires pluralization defaults, optionally registering CLDR rule fixtures via loader aware options.

func WithCultureData added in v0.2.0

func WithCultureData(path string) Option

WithCultureData configures culture data loading

func WithCultureOverride added in v0.2.0

func WithCultureOverride(locale, path string) Option

WithCultureOverride adds locale-specific culture data override

func WithDefaultLocale

func WithDefaultLocale(locale string) Option

WithDefaultLocale sets the default locale in Config

func WithFallback

func WithFallback(locale string, fallbacks ...string) Option

func WithFallbackResolver

func WithFallbackResolver(resolver FallbackResolver) Option

func WithFormatter

func WithFormatter(formatter Formatter) Option

func WithFormatterLocales added in v0.2.0

func WithFormatterLocales(locales ...string) Option

func WithFormatterProvider added in v0.2.0

func WithFormatterProvider(locale string, provider FormatterProvider) Option

func WithLoader

func WithLoader(loader Loader) Option

func WithLocales

func WithLocales(locales ...string) Option

WithLocales registers supported locales

func WithStore

func WithStore(store Store) Option

func WithTranslatorHooks

func WithTranslatorHooks(hooks ...TranslationHook) Option

type PhoneDialPlan added in v0.2.0

type PhoneDialPlan struct {
	CountryCode    string
	NationalPrefix string
	Groups         []int
}

PhoneDialPlan describes how to normalize and format phone numbers for a locale. CountryCode should be digits without the leading plus sign. NationalPrefix is optional and stripped when present. Groups defines the digit grouping for the national significant number.

func DefaultPhoneDialPlan added in v0.2.0

func DefaultPhoneDialPlan(locale string) (PhoneDialPlan, bool)

DefaultPhoneDialPlan exposes the built-in dial plan for a locale if available. It first checks the exact locale key, then falls back to the base language.

type PhoneFormatterFunc added in v0.2.0

type PhoneFormatterFunc func(locale, raw string) string

PhoneFormatterFunc formats a raw phone number string for a locale.

type PluralCategory added in v0.2.0

type PluralCategory string
const (
	PluralZero  PluralCategory = "zero"
	PluralOne   PluralCategory = "one"
	PluralTwo   PluralCategory = "two"
	PluralFew   PluralCategory = "few"
	PluralMany  PluralCategory = "many"
	PluralOther PluralCategory = "other"
)

type PluralCondition added in v0.2.0

type PluralCondition struct {
	Operand  string
	Mod      int
	Operator PluralConditionOperator
	Values   []float64
	Ranges   []PluralRange
}

type PluralConditionOperator added in v0.2.0

type PluralConditionOperator string
const (
	OperatorEquals    PluralConditionOperator = "eq"
	OperatorNotEquals PluralConditionOperator = "neq"
	OperatorIn        PluralConditionOperator = "in"
	OperatorNotIn     PluralConditionOperator = "not_in"
	OperatorWithin    PluralConditionOperator = "within"
	OperatorNotWithin PluralConditionOperator = "not_within"
)

type PluralHookMetadata added in v0.2.0

type PluralHookMetadata struct {
	Category PluralCategory
	Count    any
	Message  string
	Missing  *PluralMissingEvent
}

type PluralMissingEvent added in v0.2.0

type PluralMissingEvent struct {
	Requested PluralCategory
	Fallback  PluralCategory
}

type PluralRange added in v0.2.0

type PluralRange struct {
	Start float64
	End   float64
}

type PluralRule added in v0.2.0

type PluralRule struct {
	Category PluralCategory
	Groups   [][]PluralCondition
}

type PluralRuleSet added in v0.2.0

type PluralRuleSet struct {
	Locale      string
	DisplayName string
	Parent      string
	Rules       []PluralRule
}

func (*PluralRuleSet) Categories added in v0.2.0

func (set *PluralRuleSet) Categories() []PluralCategory

func (*PluralRuleSet) Clone added in v0.2.0

func (set *PluralRuleSet) Clone() *PluralRuleSet

Clone returns a deep copy of the rule set

type ResolveLocaleOptions added in v0.3.0

type ResolveLocaleOptions struct {
	Catalog         *LocaleCatalog
	Resolver        FallbackResolver
	DefaultLocale   string
	MatchStrategy   MatchStrategy
	Scope           LocaleScope
	ExpandParents   bool
	ExpandFallbacks bool
	IncludeDefault  bool
}

ResolveLocaleOptions configures deterministic locale resolution.

type SimpleTranslator

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

SimpleTranslator performs in memory lookups backed by a Store

func NewSimpleTranslator

func NewSimpleTranslator(store Store, opts ...SimpleTranslatorOption) (*SimpleTranslator, error)

func (*SimpleTranslator) DefaultLocale added in v0.2.0

func (t *SimpleTranslator) DefaultLocale() string

func (*SimpleTranslator) Translate

func (t *SimpleTranslator) Translate(locale, key string, args ...any) (string, error)

func (*SimpleTranslator) TranslateWithMetadata added in v0.2.0

func (t *SimpleTranslator) TranslateWithMetadata(locale, key string, args ...any) (string, map[string]any, error)

type SimpleTranslatorOption

type SimpleTranslatorOption func(*SimpleTranslator)

SimpleTranslatorOption configures SimpleTranslator

func WithTranslatorDefaultLocale

func WithTranslatorDefaultLocale(locale string) SimpleTranslatorOption

func WithTranslatorFallbackResolver

func WithTranslatorFallbackResolver(resolver FallbackResolver) SimpleTranslatorOption

func WithTranslatorFormatter

func WithTranslatorFormatter(formatter Formatter) SimpleTranslatorOption

type StaticFallbackResolver

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

StaticFallbackResolver initial imp

func NewStaticFallbackResolver

func NewStaticFallbackResolver() *StaticFallbackResolver

func (*StaticFallbackResolver) Has added in v0.3.0

func (r *StaticFallbackResolver) Has(locale string) bool

Has reports whether a locale has an explicitly configured fallback chain, including an intentionally empty chain.

func (*StaticFallbackResolver) Resolve

func (r *StaticFallbackResolver) Resolve(locale string) []string

Resolve returns a copy of the fallback chain for a locale

func (*StaticFallbackResolver) Set

func (r *StaticFallbackResolver) Set(locale string, fallbacks ...string)

Set registers the fallback chain for a locale

type StaticStore

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

StaticStore is an in memory store, read only after cosntruction

func NewStaticStore

func NewStaticStore(data Translations) *StaticStore

NewStaticStore builds an immutable snapthot from the given translations

func NewStaticStoreFromLoader

func NewStaticStoreFromLoader(loader Loader) (*StaticStore, error)

NewStaticStoreFromLoader hydrates a StaticStore using the provided loader

func (*StaticStore) Get

func (s *StaticStore) Get(locale, key string) (string, bool)

Get returns the the message template for locale/key

func (*StaticStore) Locales

func (s *StaticStore) Locales() []string

Locales returns a slice with all locale codes

func (*StaticStore) Message added in v0.2.0

func (s *StaticStore) Message(locale, key string) (Message, bool)

func (*StaticStore) Rules added in v0.2.0

func (s *StaticStore) Rules(locale string) (*PluralRuleSet, bool)

type Store

type Store interface {
	// Get returns the message template for locale/key and ok=false if missing
	Get(locale, key string) (string, bool)
	// Message returns the full message payload for locale/key
	Message(locale, key string) (Message, bool)
	// Rules returns the plural rule set for the requested locale
	Rules(locale string) (*PluralRuleSet, bool)
	// Locales returns the list of locales known to the store
	Locales() []string
}

Store exposes a read only access to translated mesasge templates

type TimeFormatRules added in v0.2.0

type TimeFormatRules struct {
	Use24Hour bool   `json:"use_24_hour"`
	Pattern   string `json:"pattern"`
}

TimeFormatRules defines time formatting

type TranslateOption added in v0.2.0

type TranslateOption interface {
	// contains filtered or unexported methods
}

TranslateOption configures translation behaviour (e.g. counts for plurals).

func WithCount added in v0.2.0

func WithCount(value any) TranslateOption

WithCount annotates a translation call with a quantity used for plural selection.

type TranslationCatalog added in v0.2.0

type TranslationCatalog struct {
	Locale        Locale
	Messages      map[string]Message
	CardinalRules *PluralRuleSet
}

type TranslationHook

type TranslationHook interface {
	BeforeTranslate(ctx *TranslatorHookContext)
	AfterTranslate(ctx *TranslatorHookContext)
}

type TranslationHookFuncs

type TranslationHookFuncs struct {
	Before func(ctx *TranslatorHookContext)
	After  func(ctx *TranslatorHookContext)
}

func (TranslationHookFuncs) AfterTranslate

func (h TranslationHookFuncs) AfterTranslate(ctx *TranslatorHookContext)

func (TranslationHookFuncs) BeforeTranslate

func (h TranslationHookFuncs) BeforeTranslate(ctx *TranslatorHookContext)

type TranslationKey

type TranslationKey struct {
	ID          string
	Domain      string
	Description string
}

TranslationKey models identifier metadata

type Translations

type Translations map[string]*TranslationCatalog

type Translator

type Translator interface {
	Translate(locale, key string, args ...any) (string, error)
}

Translator resolves a string for a given locale and message key.

func WrapTranslatorWithHooks

func WrapTranslatorWithHooks(next Translator, hooks ...TranslationHook) Translator

type TranslatorHookContext

type TranslatorHookContext struct {
	Locale   string
	Key      string
	Args     []any
	Result   string
	Error    error
	Metadata map[string]any
}

func (*TranslatorHookContext) MetadataValue

func (ctx *TranslatorHookContext) MetadataValue(key string) (any, bool)

func (*TranslatorHookContext) PluralMetadata added in v0.2.0

func (ctx *TranslatorHookContext) PluralMetadata() (PluralHookMetadata, bool)

PluralMetadata returns plural-specific hook metadata if present.

func (*TranslatorHookContext) SetMetadata

func (ctx *TranslatorHookContext) SetMetadata(key string, value any)

type TypedFormatterProvider added in v0.2.0

type TypedFormatterProvider interface {
	Formatter(name string) (any, bool)
	FuncMap() map[string]any
	Capabilities() FormatterCapabilities
}

type UnitPreference added in v0.2.0

type UnitPreference struct {
	Unit           string             `json:"unit"`
	Symbol         string             `json:"symbol"`
	ConversionFrom map[string]float64 `json:"conversion_from,omitempty"`
}

UnitPreference specifies preferred unit and conversion

Directories

Path Synopsis
cmd
example command
i18n-formatters command
examples
web command

Jump to

Keyboard shortcuts

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