@@ -15,17 +15,20 @@ import (
15
15
"code.gitea.io/gitea/modules/translation/i18n"
16
16
17
17
"golang.org/x/text/language"
18
+ "golang.org/x/text/message"
19
+ "golang.org/x/text/number"
18
20
)
19
21
20
22
type contextKey struct {}
21
23
22
- var ContextKey interface {} = & contextKey {}
24
+ var ContextKey any = & contextKey {}
23
25
24
26
// Locale represents an interface to translation
25
27
type Locale interface {
26
28
Language () string
27
- Tr (string , ... interface {}) string
28
- TrN (cnt interface {}, key1 , keyN string , args ... interface {}) string
29
+ Tr (string , ... any ) string
30
+ TrN (cnt any , key1 , keyN string , args ... any ) string
31
+ PrettyNumber (v any ) string
29
32
}
30
33
31
34
// LangType represents a lang type
@@ -135,6 +138,7 @@ func Match(tags ...language.Tag) language.Tag {
135
138
type locale struct {
136
139
i18n.Locale
137
140
Lang , LangName string // these fields are used directly in templates: .i18n.Lang
141
+ msgPrinter * message.Printer
138
142
}
139
143
140
144
// NewLocale return a locale
@@ -147,13 +151,24 @@ func NewLocale(lang string) Locale {
147
151
langName := "unknown"
148
152
if l , ok := allLangMap [lang ]; ok {
149
153
langName = l .Name
154
+ } else if len (setting .Langs ) > 0 {
155
+ lang = setting .Langs [0 ]
156
+ langName = setting .Names [0 ]
150
157
}
158
+
151
159
i18nLocale , _ := i18n .GetLocale (lang )
152
- return & locale {
160
+ l := & locale {
153
161
Locale : i18nLocale ,
154
162
Lang : lang ,
155
163
LangName : langName ,
156
164
}
165
+ if langTag , err := language .Parse (lang ); err != nil {
166
+ log .Error ("Failed to parse language tag from name %q: %v" , l .Lang , err )
167
+ l .msgPrinter = message .NewPrinter (language .English )
168
+ } else {
169
+ l .msgPrinter = message .NewPrinter (langTag )
170
+ }
171
+ return l
157
172
}
158
173
159
174
func (l * locale ) Language () string {
@@ -199,7 +214,7 @@ var trNLangRules = map[string]func(int64) int{
199
214
}
200
215
201
216
// TrN returns translated message for plural text translation
202
- func (l * locale ) TrN (cnt interface {} , key1 , keyN string , args ... interface {} ) string {
217
+ func (l * locale ) TrN (cnt any , key1 , keyN string , args ... any ) string {
203
218
var c int64
204
219
if t , ok := cnt .(int ); ok {
205
220
c = int64 (t )
@@ -223,3 +238,8 @@ func (l *locale) TrN(cnt interface{}, key1, keyN string, args ...interface{}) st
223
238
}
224
239
return l .Tr (keyN , args ... )
225
240
}
241
+
242
+ func (l * locale ) PrettyNumber (v any ) string {
243
+ // TODO: this mechanism is not good enough, the complete solution is to switch the translation system to ICU message format
244
+ return l .msgPrinter .Sprintf ("%v" , number .Decimal (v ))
245
+ }
0 commit comments