feat(html): isolate text translation fallback
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-03 19:22:48 +00:00
parent d74b65913a
commit cb75de9bf3
8 changed files with 92 additions and 16 deletions

View file

@ -1,7 +1,5 @@
package html
import i18n "dappco.re/go/core/i18n"
// context.go: Translator provides Text() lookups for a rendering context.
// Example: a locale-aware service can satisfy T(key, args...).
type Translator interface {
@ -62,11 +60,10 @@ func normaliseContext(ctx *Context) *Context {
func NewContext(locale ...string) *Context {
ctx := &Context{
Data: make(map[string]any),
service: &i18n.Service{},
service: newDefaultTranslator(),
}
if len(locale) > 0 {
ctx.Locale = locale[0]
applyLocaleToService(ctx.service, ctx.Locale)
ctx.SetLocale(locale[0])
}
return ctx
}

View file

@ -2,7 +2,12 @@
package html
import "testing"
import (
"testing"
i18n "dappco.re/go/core/i18n"
"github.com/stretchr/testify/require"
)
type localeTranslator struct {
language string
@ -87,3 +92,15 @@ func TestContext_SetService_AppliesCurrentLocale(t *testing.T) {
t.Fatalf("SetService() should apply current locale to translator, got %q", svc.language)
}
}
func TestText_RenderFallsBackToDefaultTranslator(t *testing.T) {
svc, _ := i18n.New()
i18n.SetDefault(svc)
require.NoError(t, svc.SetLanguage("fr"))
ctx := &Context{}
if got := Text("prompt.yes").Render(ctx); got != "o" {
t.Fatalf("Text() fallback translation = %q, want %q", got, "o")
}
}

View file

@ -0,0 +1,11 @@
//go:build !js
// SPDX-Licence-Identifier: EUPL-1.2
package html
import i18n "dappco.re/go/core/i18n"
func newDefaultTranslator() Translator {
return &i18n.Service{}
}

29
default_translator_js.go Normal file
View file

@ -0,0 +1,29 @@
//go:build js
// SPDX-Licence-Identifier: EUPL-1.2
package html
type defaultTranslator struct {
language string
}
func (t *defaultTranslator) T(key string, args ...any) string {
_ = t.language
if len(args) == 0 {
return key
}
return key
}
func (t *defaultTranslator) SetLanguage(language string) error {
if t == nil {
return nil
}
t.language = language
return nil
}
func newDefaultTranslator() Translator {
return &defaultTranslator{}
}

11
node.go
View file

@ -7,8 +7,6 @@ import (
"slices"
"strconv"
"strings"
i18n "dappco.re/go/core/i18n"
)
// node.go: Node is anything renderable.
@ -440,14 +438,7 @@ func (n *textNode) Render(ctx *Context) string {
return ""
}
ctx = normaliseContext(ctx)
var text string
if ctx.service != nil {
text = ctx.service.T(n.key, n.args...)
} else {
text = i18n.T(n.key, n.args...)
}
return escapeHTML(text)
return escapeHTML(translateText(ctx, n.key, n.args...))
}
// --- ifNode ---

11
text_translate.go Normal file
View file

@ -0,0 +1,11 @@
// SPDX-Licence-Identifier: EUPL-1.2
package html
func translateText(ctx *Context, key string, args ...any) string {
if ctx != nil && ctx.service != nil {
return ctx.service.T(key, args...)
}
return translateDefault(key, args...)
}

11
text_translate_default.go Normal file
View file

@ -0,0 +1,11 @@
//go:build !js
// SPDX-Licence-Identifier: EUPL-1.2
package html
import i18n "dappco.re/go/core/i18n"
func translateDefault(key string, args ...any) string {
return i18n.T(key, args...)
}

9
text_translate_js.go Normal file
View file

@ -0,0 +1,9 @@
//go:build js
// SPDX-Licence-Identifier: EUPL-1.2
package html
func translateDefault(key string, _ ...any) string {
return key
}