From 6bf02fd0bdafa6ac390e7b0580ceed99826b5916 Mon Sep 17 00:00:00 2001 From: Virgil Date: Wed, 1 Apr 2026 23:53:16 +0000 Subject: [PATCH] feat(i18n): add location to translation context Co-Authored-By: Virgil --- context.go | 52 ++++++++++++++++++++++++++++++++++++++++--------- context_test.go | 15 ++++++++++++++ i18n.go | 1 + service.go | 2 +- service_test.go | 4 ++++ 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/context.go b/context.go index 7c53b5e..53722f4 100644 --- a/context.go +++ b/context.go @@ -7,6 +7,7 @@ package i18n type TranslationContext struct { Context string Gender string + Location string Formality Formality Extra map[string]any } @@ -17,31 +18,49 @@ func C(context string) *TranslationContext { } func (c *TranslationContext) WithGender(gender string) *TranslationContext { - if c == nil { return nil } + if c == nil { + return nil + } c.Gender = gender return c } +func (c *TranslationContext) In(location string) *TranslationContext { + if c == nil { + return nil + } + c.Location = location + return c +} + func (c *TranslationContext) Formal() *TranslationContext { - if c == nil { return nil } + if c == nil { + return nil + } c.Formality = FormalityFormal return c } func (c *TranslationContext) Informal() *TranslationContext { - if c == nil { return nil } + if c == nil { + return nil + } c.Formality = FormalityInformal return c } func (c *TranslationContext) WithFormality(f Formality) *TranslationContext { - if c == nil { return nil } + if c == nil { + return nil + } c.Formality = f return c } func (c *TranslationContext) Set(key string, value any) *TranslationContext { - if c == nil { return nil } + if c == nil { + return nil + } if c.Extra == nil { c.Extra = make(map[string]any) } @@ -50,21 +69,36 @@ func (c *TranslationContext) Set(key string, value any) *TranslationContext { } func (c *TranslationContext) Get(key string) any { - if c == nil || c.Extra == nil { return nil } + if c == nil || c.Extra == nil { + return nil + } return c.Extra[key] } func (c *TranslationContext) ContextString() string { - if c == nil { return "" } + if c == nil { + return "" + } return c.Context } func (c *TranslationContext) GenderString() string { - if c == nil { return "" } + if c == nil { + return "" + } return c.Gender } +func (c *TranslationContext) LocationString() string { + if c == nil { + return "" + } + return c.Location +} + func (c *TranslationContext) FormalityValue() Formality { - if c == nil { return FormalityNeutral } + if c == nil { + return FormalityNeutral + } return c.Formality } diff --git a/context_test.go b/context_test.go index 31fe215..870664d 100644 --- a/context_test.go +++ b/context_test.go @@ -28,6 +28,7 @@ func TestTranslationContext_NilReceiver_Good(t *testing.T) { var ctx *TranslationContext assert.Nil(t, ctx.WithGender("masculine")) + assert.Nil(t, ctx.In("workspace")) assert.Nil(t, ctx.Formal()) assert.Nil(t, ctx.Informal()) assert.Nil(t, ctx.WithFormality(FormalityFormal)) @@ -35,6 +36,7 @@ func TestTranslationContext_NilReceiver_Good(t *testing.T) { assert.Nil(t, ctx.Get("key")) assert.Equal(t, "", ctx.ContextString()) assert.Equal(t, "", ctx.GenderString()) + assert.Equal(t, "", ctx.LocationString()) assert.Equal(t, FormalityNeutral, ctx.FormalityValue()) } @@ -46,6 +48,17 @@ func TestTranslationContext_WithGender_Good(t *testing.T) { assert.Equal(t, "feminine", ctx.GenderString()) } +func TestTranslationContext_In_Good(t *testing.T) { + ctx := C("test").In("workspace") + assert.Equal(t, "workspace", ctx.Location) + assert.Equal(t, "workspace", ctx.LocationString()) +} + +func TestTranslationContext_In_Bad_NilReceiver(t *testing.T) { + var ctx *TranslationContext + assert.Nil(t, ctx.In("workspace")) +} + // --- Formal / Informal --- func TestTranslationContext_Formal_Good(t *testing.T) { @@ -106,11 +119,13 @@ func TestTranslationContext_Get_Bad_NilExtra(t *testing.T) { func TestTranslationContext_FullChain_Good(t *testing.T) { ctx := C("medical"). WithGender("feminine"). + In("clinic"). Formal(). Set("speciality", "cardiology") assert.Equal(t, "medical", ctx.ContextString()) assert.Equal(t, "feminine", ctx.GenderString()) + assert.Equal(t, "clinic", ctx.LocationString()) assert.Equal(t, FormalityFormal, ctx.FormalityValue()) assert.Equal(t, "cardiology", ctx.Get("speciality")) } diff --git a/i18n.go b/i18n.go index a86c06b..ba7bff6 100644 --- a/i18n.go +++ b/i18n.go @@ -162,6 +162,7 @@ func templateDataForRendering(data any) any { rendered := map[string]any{ "Context": v.Context, "Gender": v.Gender, + "Location": v.Location, "Formality": v.Formality, "Extra": v.Extra, } diff --git a/service.go b/service.go index 79fde2d..54a8ba1 100644 --- a/service.go +++ b/service.go @@ -399,7 +399,7 @@ func (s *Service) getEffectiveContextGenderLocationAndFormality(data any) (strin if formality == FormalityNeutral { formality = s.formality } - return ctx.ContextString(), ctx.GenderString(), "", formality + return ctx.ContextString(), ctx.GenderString(), ctx.LocationString(), formality } if subj, ok := data.(*Subject); ok && subj != nil { formality := subj.formality diff --git a/service_test.go b/service_test.go index 227126c..ec46076 100644 --- a/service_test.go +++ b/service_test.go @@ -257,6 +257,10 @@ func TestServiceTranslationContext(t *testing.T) { t.Errorf("T(direction.right, C(navigation).WithGender(feminine).Formal()) = %q, want %q", got, "right, madam") } + if got := svc.T("welcome", C("greeting").In("workspace")); got != "welcome aboard" { + t.Errorf("T(welcome, C(greeting).In(workspace)) = %q, want %q", got, "welcome aboard") + } + if got := svc.T("welcome", S("user", "Alice").Gender("feminine")); got != "welcome, ma'am" { t.Errorf("T(welcome, S(user, Alice).Gender(feminine)) = %q, want %q", got, "welcome, ma'am") } -- 2.45.3