go-html/context.go
Virgil 6f65fc903c
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
feat(html): restore context mutators
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-03 18:48:46 +00:00

102 lines
2.7 KiB
Go

package html
// context.go: Translator provides Text() lookups for a rendering context.
// Example: a locale-aware service can satisfy T(key, args...).
type Translator interface {
T(key string, args ...any) string
}
// context.go: Context carries rendering state through the node tree.
// Example: NewContext("en-GB") initialises locale-specific rendering state.
// Locale and translator selection happen at construction time.
type Context struct {
Identity string
Locale string
Entitlements func(feature string) bool
Data map[string]any
service Translator
}
func applyLocaleToService(svc Translator, locale string) {
if svc == nil || locale == "" {
return
}
if setter, ok := svc.(interface{ SetLanguage(string) error }); ok {
base := locale
for i := 0; i < len(base); i++ {
if base[i] == '-' || base[i] == '_' {
base = base[:i]
break
}
}
_ = setter.SetLanguage(base)
}
}
// ensureContextDefaults initialises lazily-created context fields.
func ensureContextDefaults(ctx *Context) {
if ctx == nil {
return
}
if ctx.Data == nil {
ctx.Data = make(map[string]any)
}
}
// normaliseContext ensures render paths always have a usable context.
// A nil input is replaced with a fresh default context.
func normaliseContext(ctx *Context) *Context {
if ctx != nil {
ensureContextDefaults(ctx)
return ctx
}
return NewContext()
}
// context.go: NewContext creates a new rendering context with sensible defaults.
// Example: ctx := NewContext("en-GB").
// An optional locale may be provided as the first argument.
func NewContext(locale ...string) *Context {
ctx := &Context{
Data: make(map[string]any),
}
if len(locale) > 0 {
ctx.Locale = locale[0]
}
return ctx
}
// context.go: NewContextWithService creates a rendering context backed by a specific translator.
// Example: ctx := NewContextWithService(svc, "fr-FR").
// An optional locale may be provided as the second argument.
func NewContextWithService(svc Translator, locale ...string) *Context {
ctx := NewContext(locale...)
return ctx.SetService(svc)
}
// context.go: SetService swaps the translator used by the context.
// Example: ctx.SetService(svc).
func (ctx *Context) SetService(svc Translator) *Context {
if ctx == nil {
return nil
}
ensureContextDefaults(ctx)
ctx.service = svc
applyLocaleToService(svc, ctx.Locale)
return ctx
}
// context.go: SetLocale updates the context locale and reapplies it to the active translator.
// Example: ctx.SetLocale("en-US").
func (ctx *Context) SetLocale(locale string) *Context {
if ctx == nil {
return nil
}
ensureContextDefaults(ctx)
ctx.Locale = locale
applyLocaleToService(ctx.service, ctx.Locale)
return ctx
}