Skip to content

Commit 2c8a2b9

Browse files
fix issue4:panic without _example/localize/en.yaml
1 parent 79c461e commit 2c8a2b9

File tree

10 files changed

+210
-3
lines changed

10 files changed

+210
-3
lines changed

_example/i18n/de.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"welcome": "hallo",
3+
"welcomeWithName": "hallo {{ .name }}"
4+
}

_example/i18n/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"welcome": "hello",
3+
"welcomeWithName": "hello {{ .name }}"
4+
}

_example/i18n/fr.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"welcome": "bonjour",
3+
"welcomeWithName": "bonjour {{ .name }}"
4+
}

_example/i18n/zh.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"welcomeWithNameAndFood":"欢迎宝贝{{ .name }}, 我喜欢吃 {{ .food }}",
3+
"welcome": "欢迎"
4+
}

_example/main.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package main
22

33
import (
4+
"encoding/json"
45
"log"
56
"net/http"
67

78
ginI18n "github.com/gin-contrib/i18n"
89
"github.com/gin-gonic/gin"
910
"github.com/nicksnyder/go-i18n/v2/i18n"
11+
"golang.org/x/text/language"
1012
)
1113

1214
func main() {
@@ -15,7 +17,13 @@ func main() {
1517
router := gin.New()
1618

1719
// apply i18n middleware
18-
router.Use(ginI18n.Localize())
20+
r.Use(ginI18n.Localize(ginI18n.WithBundle(&ginI18n.BundleCfg{
21+
RootPath: "./i18n",
22+
AcceptLanguage: []language.Tag{language.Chinese, language.English},
23+
DefaultLanguage: language.English,
24+
FormatBundleFile: "json",
25+
UnmarshalFunc: json.Unmarshal,
26+
})))
1927

2028
router.GET("/", func(context *gin.Context) {
2129
context.String(http.StatusOK, ginI18n.MustGetMessage("welcome"))

ginI18n.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"reflect"
78

89
"github.com/gin-gonic/gin"
910
"github.com/nicksnyder/go-i18n/v2/i18n"
@@ -50,6 +51,28 @@ func (i *ginI18nImpl) setCurrentContext(ctx context.Context) {
5051
i.currentContext = ctx.(*gin.Context)
5152
}
5253

54+
func (ginI18nImpl) setCustomerBundle(cfg *BundleCfg) {
55+
if !reflect.DeepEqual(cfg.DefaultLanguage, language.Tag{}) {
56+
defaultBundleConfig.DefaultLanguage = cfg.DefaultLanguage
57+
}
58+
59+
if len(cfg.AcceptLanguage) != 0 {
60+
defaultBundleConfig.AcceptLanguage = cfg.AcceptLanguage
61+
}
62+
63+
if cfg.FormatBundleFile != "" {
64+
defaultBundleConfig.FormatBundleFile = cfg.FormatBundleFile
65+
}
66+
67+
if cfg.RootPath != "" {
68+
defaultBundleConfig.RootPath = cfg.RootPath
69+
}
70+
71+
if cfg.UnmarshalFunc != nil {
72+
defaultBundleConfig.UnmarshalFunc = cfg.UnmarshalFunc
73+
}
74+
}
75+
5376
func (i *ginI18nImpl) setBundle(cfg *BundleCfg) {
5477
bundle := i18n.NewBundle(cfg.DefaultLanguage)
5578
bundle.RegisterUnmarshalFunc(cfg.FormatBundleFile, cfg.UnmarshalFunc)

i18n.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ func newI18n(opts ...Option) {
1212
ins := &ginI18nImpl{
1313
getLngHandler: defaultGetLngHandler,
1414
}
15-
ins.setBundle(defaultBundleConfig)
1615

1716
// overwrite default value by options
1817
for _, opt := range opts {
1918
opt(ins)
2019
}
2120

21+
ins.setBundle(defaultBundleConfig)
22+
2223
atI18n = ins
2324
}
2425

i18n_test.go

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package i18n
22

33
import (
4+
"encoding/json"
45
"net/http"
56
"net/http/httptest"
67
"testing"
@@ -14,6 +15,55 @@ func init() {
1415
gin.SetMode(gin.ReleaseMode)
1516
}
1617

18+
func newPartCustomerConfigServer() *gin.Engine {
19+
router := gin.New()
20+
router.Use(Localize(WithBundle(&BundleCfg{
21+
RootPath: "./_example/i18n",
22+
FormatBundleFile: "json",
23+
})))
24+
25+
router.GET("/", func(context *gin.Context) {
26+
context.String(http.StatusOK, MustGetMessage("welcome"))
27+
})
28+
29+
router.GET("/:name", func(context *gin.Context) {
30+
context.String(http.StatusOK, MustGetMessage(&i18n.LocalizeConfig{
31+
MessageID: "welcomeWithName",
32+
TemplateData: map[string]string{
33+
"name": context.Param("name"),
34+
},
35+
}))
36+
})
37+
38+
return router
39+
}
40+
func newCustomerServer() *gin.Engine {
41+
router := gin.New()
42+
router.Use(Localize(WithBundle(&BundleCfg{
43+
RootPath: "./_example/i18n",
44+
AcceptLanguage: []language.Tag{language.Chinese, language.English},
45+
DefaultLanguage: language.English,
46+
FormatBundleFile: "json",
47+
UnmarshalFunc: json.Unmarshal,
48+
})))
49+
50+
router.GET("/", func(context *gin.Context) {
51+
context.String(http.StatusOK, MustGetMessage("welcome"))
52+
})
53+
54+
router.GET("/:name/:food", func(context *gin.Context) {
55+
context.String(http.StatusOK, MustGetMessage(&i18n.LocalizeConfig{
56+
MessageID: "welcomeWithNameAndFood",
57+
TemplateData: map[string]string{
58+
"name": context.Param("name"),
59+
"food": context.Param("food"),
60+
},
61+
}))
62+
})
63+
64+
return router
65+
}
66+
1767
// newServer ...
1868
func newServer() *gin.Engine {
1969
router := gin.New()
@@ -35,6 +85,39 @@ func newServer() *gin.Engine {
3585
return router
3686
}
3787

88+
func makeRequest3(
89+
lng language.Tag,
90+
name string,
91+
) string {
92+
path := "/" + name
93+
req, _ := http.NewRequest("GET", path, nil)
94+
req.Header.Add("Accept-Language", lng.String())
95+
96+
// Perform the request
97+
w := httptest.NewRecorder()
98+
r := newPartCustomerConfigServer()
99+
r.ServeHTTP(w, req)
100+
101+
return w.Body.String()
102+
}
103+
104+
func makeRequest2(
105+
lng language.Tag,
106+
name string,
107+
food string,
108+
) string {
109+
path := "/" + name + "/" + food
110+
req, _ := http.NewRequest("GET", path, nil)
111+
req.Header.Add("Accept-Language", lng.String())
112+
113+
// Perform the request
114+
w := httptest.NewRecorder()
115+
r := newCustomerServer()
116+
r.ServeHTTP(w, req)
117+
118+
return w.Body.String()
119+
}
120+
38121
// makeRequest ...
39122
func makeRequest(
40123
lng language.Tag,
@@ -159,3 +242,78 @@ func TestI18nFR(t *testing.T) {
159242
})
160243
}
161244
}
245+
246+
func TestCustomerI18n(t *testing.T) {
247+
type args struct {
248+
lng language.Tag
249+
name string
250+
food string
251+
}
252+
tests := []struct {
253+
name string
254+
args args
255+
want string
256+
}{
257+
{
258+
name: "1st",
259+
args: args{
260+
name: "watch",
261+
food: "apple",
262+
lng: language.Chinese,
263+
},
264+
want: "欢迎宝贝watch, 我喜欢吃 apple",
265+
},
266+
{
267+
name: "2nd",
268+
args: args{
269+
name: "issues",
270+
food: "orange",
271+
lng: language.English,
272+
},
273+
want: "welcome my baby issues,I like orange",
274+
},
275+
}
276+
for _, tt := range tests {
277+
t.Run(tt.name, func(t *testing.T) {
278+
if got := makeRequest2(tt.args.lng, tt.args.name, tt.args.food); got != tt.want {
279+
t.Errorf("makeRequest2() = %v, want %v", got, tt.want)
280+
}
281+
})
282+
}
283+
}
284+
285+
func TestPartCustomerConfigI18n(t *testing.T) {
286+
type args struct {
287+
lng language.Tag
288+
name string
289+
}
290+
tests := []struct {
291+
name string
292+
args args
293+
want string
294+
}{
295+
{
296+
name: "hello world",
297+
args: args{
298+
name: "",
299+
lng: language.English,
300+
},
301+
want: "hello",
302+
},
303+
{
304+
name: "hello alex",
305+
args: args{
306+
name: "alex",
307+
lng: language.English,
308+
},
309+
want: "hello alex",
310+
},
311+
}
312+
for _, tt := range tests {
313+
t.Run(tt.name, func(t *testing.T) {
314+
if got := makeRequest3(tt.args.lng, tt.args.name); got != tt.want {
315+
t.Errorf("makeRequest3() = %v, want %v", got, tt.want)
316+
}
317+
})
318+
}
319+
}

interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ type GinI18n interface {
1111

1212
setCurrentContext(ctx context.Context)
1313
setBundle(cfg *BundleCfg)
14+
setCustomerBundle(cfg *BundleCfg)
1415
setGetLngHandler(handler GetLngHandler)
1516
}

option.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type BundleCfg struct {
1717
// WithBundle ...
1818
func WithBundle(config *BundleCfg) Option {
1919
return func(g GinI18n) {
20-
g.setBundle(config)
20+
g.setCustomerBundle(config)
2121
}
2222
}
2323

0 commit comments

Comments
 (0)