Localization (i18n)

The locale package provides internationalization support. Register translations per locale, resolve strings with T(), and auto-detect locale from Accept-Language headers via middleware.

Setup

import "github.com/CodeSyncr/nimbus/locale"

func init() {
    // Set default locale
    locale.SetDefault("en")

    // Register English translations
    locale.AddTranslations("en", map[string]string{
        "welcome":       "Welcome, %s!",
        "items.count":   "You have %d items",
        "auth.login":    "Log In",
        "auth.logout":   "Log Out",
        "errors.not_found": "Page not found",
    })

    // Register Spanish translations
    locale.AddTranslations("es", map[string]string{
        "welcome":       "¡Bienvenido, %s!",
        "items.count":   "Tienes %d artículos",
        "auth.login":    "Iniciar sesión",
        "auth.logout":   "Cerrar sesión",
        "errors.not_found": "Página no encontrada",
    })
}

Translating Strings

Use T() with the default locale, or TLocale() for a specific locale:

// Uses default locale ("en")
msg := locale.T("welcome", "Jane")   // "Welcome, Jane!"
count := locale.T("items.count", 5)  // "You have 5 items"

// Specific locale
msg = locale.TLocale("es", "welcome", "Jane")  // "¡Bienvenido, Jane!"

// Key fallback — if key not found, returns the key itself
msg = locale.T("unknown.key")  // "unknown.key"

Middleware (Auto-detect)

The locale middleware parses Accept-Language and stores the locale in the request context:

// Add to global middleware
app.Router.Use(locale.Middleware())

Context Helpers

// In a controller — get locale from request context
func Dashboard(c *http.Context) error {
    loc := locale.FromContext(c.Request.Context())
    // loc might be "es", "fr", "en", etc.

    welcome := locale.TLocale(loc, "welcome", user.Name)
    return c.View("dashboard", map[string]any{
        "welcome": welcome,
    })
}

// Manually set locale on a context
ctx := locale.WithLocale(c.Request.Context(), "fr")

API Reference

FunctionDescription
SetDefault(loc)Set the default locale (e.g. "en")
AddTranslations(loc, msgs)Register key→message pairs for a locale
T(key, args...)Translate using default locale; supports fmt.Sprintf args
TLocale(loc, key, args...)Translate using a specific locale
WithLocale(ctx, loc)Store locale in context
FromContext(ctx)Retrieve locale from context (empty string if not set)
Middleware()Auto-detect locale from Accept-Language header

Using in Templates

{{-- Pass translated strings from controller --}}
<h1>{{ welcome }}</h1>
<a href="/login">{{ loginText }}</a>

Organizing Translations

For larger apps, organize translation files by locale and load them at boot:

package lang

var EN = map[string]string{
    "welcome":          "Welcome, %s!",
    "items.count":      "You have %d items",
    "auth.login":       "Log In",
    "auth.logout":      "Log Out",
    "auth.register":    "Register",
    "nav.dashboard":    "Dashboard",
    "nav.settings":     "Settings",
    "errors.not_found": "Page not found",
    "errors.forbidden": "Access denied",
}

// In kernel.go:
// locale.AddTranslations("en", lang.EN)
// locale.AddTranslations("es", lang.ES)

String Interpolation

Translation values use Go's fmt.Sprintf formatting. Use %s for strings, %d for integers, %f for floats. If no args are passed, the message is returned as-is. If the key is not found, the key itself is returned — which makes it safe to use untranslated keys during development.