forked from gin-contrib/i18n
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ginI18n.go
141 lines (116 loc) · 3.38 KB
/
ginI18n.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package i18n
import (
"errors"
"fmt"
"path"
"github.com/gin-gonic/gin"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
var _ GinI18n = (*ginI18nImpl)(nil)
type ginI18nImpl struct {
bundle *i18n.Bundle
localizerByLng map[string]*i18n.Localizer
defaultLanguage language.Tag
getLngHandler GetLngHandler
}
// getMessage get localize message by lng and messageID
func (i *ginI18nImpl) getMessage(ctx *gin.Context, param interface{}) (string, error) {
lng := i.getLngHandler(ctx, i.defaultLanguage.String())
localizer := i.getLocalizerByLng(lng)
localizeConfig, err := i.getLocalizeConfig(param)
if err != nil {
return "", err
}
message, err := localizer.Localize(localizeConfig)
if err != nil {
return "", err
}
return message, nil
}
// mustGetMessage ...
func (i *ginI18nImpl) mustGetMessage(ctx *gin.Context, param interface{}) string {
message, _ := i.getMessage(ctx, param)
return message
}
func (i *ginI18nImpl) setBundle(cfg *BundleCfg) {
bundle := i18n.NewBundle(cfg.DefaultLanguage)
bundle.RegisterUnmarshalFunc(cfg.FormatBundleFile, cfg.UnmarshalFunc)
i.bundle = bundle
i.defaultLanguage = cfg.DefaultLanguage
i.loadMessageFiles(cfg)
i.setLocalizerByLng(cfg.AcceptLanguage)
}
func (i *ginI18nImpl) setGetLngHandler(handler GetLngHandler) {
i.getLngHandler = handler
}
// loadMessageFiles load all file localize to bundle
func (i *ginI18nImpl) loadMessageFiles(config *BundleCfg) {
for _, lng := range config.AcceptLanguage {
src := path.Join(config.RootPath, lng.String()) + "." + config.FormatBundleFile
if err := i.loadMessageFile(config, src); err != nil {
panic(err)
}
}
}
func (i *ginI18nImpl) loadMessageFile(config *BundleCfg, src string) error {
buf, err := config.Loader.LoadMessage(src)
if err != nil {
return err
}
if _, err = i.bundle.ParseMessageFileBytes(buf, src); err != nil {
return err
}
return nil
}
// setLocalizerByLng set localizer by language
func (i *ginI18nImpl) setLocalizerByLng(acceptLanguage []language.Tag) {
i.localizerByLng = map[string]*i18n.Localizer{}
for _, lng := range acceptLanguage {
lngStr := lng.String()
i.localizerByLng[lngStr] = i.newLocalizer(lngStr)
}
// set defaultLanguage if it isn't exist
defaultLng := i.defaultLanguage.String()
if _, hasDefaultLng := i.localizerByLng[defaultLng]; !hasDefaultLng {
i.localizerByLng[defaultLng] = i.newLocalizer(defaultLng)
}
}
// newLocalizer create a localizer by language
func (i *ginI18nImpl) newLocalizer(lng string) *i18n.Localizer {
lngDefault := i.defaultLanguage.String()
lngs := []string{
lng,
}
if lng != lngDefault {
lngs = append(lngs, lngDefault)
}
localizer := i18n.NewLocalizer(
i.bundle,
lngs...,
)
return localizer
}
// getLocalizerByLng get localizer by language
func (i *ginI18nImpl) getLocalizerByLng(lng string) *i18n.Localizer {
localizer, hasValue := i.localizerByLng[lng]
if hasValue {
return localizer
}
return i.localizerByLng[i.defaultLanguage.String()]
}
func (i *ginI18nImpl) getLocalizeConfig(param interface{}) (*i18n.LocalizeConfig, error) {
switch paramValue := param.(type) {
case string:
localizeConfig := &i18n.LocalizeConfig{
MessageID: paramValue,
}
return localizeConfig, nil
case *i18n.LocalizeConfig:
return paramValue, nil
case i18n.LocalizeConfig:
return ¶mValue, nil
}
msg := fmt.Sprintf("un supported localize param: %v", param)
return nil, errors.New(msg)
}