Skip to content

Commit 9b6b5df

Browse files
committed
fix
1 parent 3da2c63 commit 9b6b5df

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

modules/translation/i18n/i18n_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package i18n
55

66
import (
7+
"html/template"
78
"strings"
89
"testing"
910

@@ -82,6 +83,71 @@ c=22
8283
assert.Equal(t, "22", lang1.TrString("c"))
8384
}
8485

86+
type stringerPointerReceiver struct {
87+
s string
88+
}
89+
90+
func (s *stringerPointerReceiver) String() string {
91+
return s.s
92+
}
93+
94+
type stringerStructReceiver struct {
95+
s string
96+
}
97+
98+
func (s stringerStructReceiver) String() string {
99+
return s.s
100+
}
101+
102+
type errorStructReceiver struct {
103+
s string
104+
}
105+
106+
func (e errorStructReceiver) Error() string {
107+
return e.s
108+
}
109+
110+
type errorPointerReceiver struct {
111+
s string
112+
}
113+
114+
func (e *errorPointerReceiver) Error() string {
115+
return e.s
116+
}
117+
118+
func TestLocaleWithTemplate(t *testing.T) {
119+
ls := NewLocaleStore()
120+
assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", []byte(`key=<a>%s</a>`), nil))
121+
lang1, _ := ls.Locale("lang1")
122+
123+
tmpl := template.New("test").Funcs(template.FuncMap{"tr": lang1.TrHTML})
124+
tmpl = template.Must(tmpl.Parse(`{{tr "key" .var}}`))
125+
126+
cases := []struct {
127+
in any
128+
want string
129+
}{
130+
{"<str>", "<a>&lt;str&gt;</a>"},
131+
{[]byte("<bytes>"), "<a>[60 98 121 116 101 115 62]</a>"},
132+
{template.HTML("<html>"), "<a><html></a>"},
133+
{stringerPointerReceiver{"<stringerPointerReceiver>"}, "<a>{&lt;stringerPointerReceiver&gt;}</a>"},
134+
{&stringerPointerReceiver{"<stringerPointerReceiver ptr>"}, "<a>&lt;stringerPointerReceiver ptr&gt;</a>"},
135+
{stringerStructReceiver{"<stringerStructReceiver>"}, "<a>&lt;stringerStructReceiver&gt;</a>"},
136+
{&stringerStructReceiver{"<stringerStructReceiver ptr>"}, "<a>&lt;stringerStructReceiver ptr&gt;</a>"},
137+
{errorStructReceiver{"<errorStructReceiver>"}, "<a>&lt;errorStructReceiver&gt;</a>"},
138+
{&errorStructReceiver{"<errorStructReceiver ptr>"}, "<a>&lt;errorStructReceiver ptr&gt;</a>"},
139+
{errorPointerReceiver{"<errorPointerReceiver>"}, "<a>{&lt;errorPointerReceiver&gt;}</a>"},
140+
{&errorPointerReceiver{"<errorPointerReceiver ptr>"}, "<a>&lt;errorPointerReceiver ptr&gt;</a>"},
141+
}
142+
143+
buf := &strings.Builder{}
144+
for _, c := range cases {
145+
buf.Reset()
146+
assert.NoError(t, tmpl.Execute(buf, map[string]any{"var": c.in}))
147+
assert.Equal(t, c.want, buf.String())
148+
}
149+
}
150+
85151
func TestLocaleStoreQuirks(t *testing.T) {
86152
const nl = "\n"
87153
q := func(q1, s string, q2 ...string) string {

modules/translation/i18n/localestore.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,14 @@ func (l *locale) TrHTML(trKey string, trArgs ...any) template.HTML {
133133
args := slices.Clone(trArgs)
134134
for i, v := range args {
135135
switch v := v.(type) {
136+
case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, template.HTML:
137+
// for most basic types (including template.HTML which is safe), just do nothing and use it
136138
case string:
137-
args[i] = template.HTML(template.HTMLEscapeString(v))
139+
args[i] = template.HTMLEscapeString(v)
138140
case fmt.Stringer:
139141
args[i] = template.HTMLEscapeString(v.String())
140-
default: // int, float, include template.HTML
141-
// do nothing, just use it
142+
default:
143+
args[i] = template.HTMLEscapeString(fmt.Sprint(v))
142144
}
143145
}
144146
return template.HTML(l.TrString(trKey, args...))

0 commit comments

Comments
 (0)