diff --git a/node_test.go b/node_test.go index a26cdcd..f3b8756 100644 --- a/node_test.go +++ b/node_test.go @@ -65,6 +65,45 @@ func TestTextNode_Render_Good(t *testing.T) { } } +func TestTextNode_UsesContextDataForCount_Good(t *testing.T) { + svc, _ := i18n.New() + i18n.SetDefault(svc) + + tests := []struct { + name string + key string + data map[string]any + want string + }{ + { + name: "capitalised count", + key: "i18n.count.file", + data: map[string]any{"Count": 5}, + want: "5 files", + }, + { + name: "lowercase count", + key: "i18n.count.file", + data: map[string]any{"count": 1}, + want: "1 file", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := NewContext() + for k, v := range tt.data { + ctx.Metadata[k] = v + } + + got := Text(tt.key).Render(ctx) + if got != tt.want { + t.Fatalf("Text(%q).Render() = %q, want %q", tt.key, got, tt.want) + } + }) + } +} + func TestTextNode_Escapes_Good(t *testing.T) { ctx := NewContext() node := Text("") diff --git a/text_translate.go b/text_translate.go index 4e3ee8f..3dbf404 100644 --- a/text_translate.go +++ b/text_translate.go @@ -3,8 +3,11 @@ package html func translateText(ctx *Context, key string, args ...any) string { - if ctx != nil && ctx.service != nil { - return ctx.service.T(key, args...) + if ctx != nil { + args = translationArgs(ctx, key, args) + if ctx.service != nil { + return ctx.service.T(key, args...) + } } return translateDefault(key, args...) diff --git a/text_translate_default.go b/text_translate_default.go index 3bb280c..0ad60ce 100644 --- a/text_translate_default.go +++ b/text_translate_default.go @@ -4,7 +4,91 @@ package html -import i18n "dappco.re/go/core/i18n" +import ( + "strconv" + "strings" + + i18n "dappco.re/go/core/i18n" +) + +func translationArgs(ctx *Context, key string, args []any) []any { + if ctx == nil || len(ctx.Data) == 0 { + return args + } + + count, ok := contextCount(ctx.Data) + if !ok { + return args + } + + if len(args) == 0 { + return []any{count} + } + if strings.HasPrefix(key, "i18n.count.") && !isCountLike(args[0]) { + return append([]any{count}, args...) + } + return args +} + +func contextCount(data map[string]any) (int, bool) { + if len(data) == 0 { + return 0, false + } + if v, ok := data["Count"]; ok { + if n, ok := countInt(v); ok { + return n, true + } + } + if v, ok := data["count"]; ok { + if n, ok := countInt(v); ok { + return n, true + } + } + return 0, false +} + +func countInt(v any) (int, bool) { + switch n := v.(type) { + case int: + return n, true + case int8: + return int(n), true + case int16: + return int(n), true + case int32: + return int(n), true + case int64: + return int(n), true + case uint: + return int(n), true + case uint8: + return int(n), true + case uint16: + return int(n), true + case uint32: + return int(n), true + case uint64: + return int(n), true + case float32: + return int(n), true + case float64: + return int(n), true + case string: + n = strings.TrimSpace(n) + if n == "" { + return 0, false + } + if parsed, err := strconv.Atoi(n); err == nil { + return parsed, true + } + } + return 0, false +} + +func isCountLike(v any) bool { + _, ok := countInt(v) + return ok +} func translateDefault(key string, args ...any) string { return i18n.T(key, args...) diff --git a/text_translate_js.go b/text_translate_js.go index 692e4c9..70e0a1a 100644 --- a/text_translate_js.go +++ b/text_translate_js.go @@ -4,6 +4,10 @@ package html +func translationArgs(_ *Context, _ string, args []any) []any { + return args +} + func translateDefault(key string, _ ...any) string { return key }