1 package main
2
3 import (
4 "context"
5 "html/template"
6 "log"
7 "net/http"
8 "time"
9
10 "github.com/go-playground/locales"
11 "github.com/go-playground/locales/currency"
12 "github.com/go-playground/locales/en"
13 "github.com/go-playground/locales/fr"
14 "github.com/go-playground/pure/v5"
15 "github.com/go-playground/pure/v5/_examples/middleware/logging-recovery"
16 "github.com/go-playground/universal-translator"
17 )
18
19 var (
20 tmpls *template.Template
21 utrans *ut.UniversalTranslator
22 transKey = struct {
23 name string
24 }{
25 name: "transKey",
26 }
27 )
28
29
30
31
32 type Translator interface {
33 locales.Translator
34
35
36
37 T(key interface{}, params ...string) string
38
39
40
41
42 C(key interface{}, num float64, digits uint64, param string) string
43
44
45
46
47 O(key interface{}, num float64, digits uint64, param string) string
48
49
50
51
52 R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) string
53
54
55 Currency() currency.Type
56 }
57
58
59 type translator struct {
60 locales.Translator
61 trans ut.Translator
62 }
63
64 var _ Translator = (*translator)(nil)
65
66 func (t *translator) T(key interface{}, params ...string) string {
67
68 s, err := t.trans.T(key, params...)
69 if err != nil {
70 log.Printf("issue translating key: '%v' error: '%s'", key, err)
71 }
72
73 return s
74 }
75
76 func (t *translator) C(key interface{}, num float64, digits uint64, param string) string {
77
78 s, err := t.trans.C(key, num, digits, param)
79 if err != nil {
80 log.Printf("issue translating cardinal key: '%v' error: '%s'", key, err)
81 }
82
83 return s
84 }
85
86 func (t *translator) O(key interface{}, num float64, digits uint64, param string) string {
87
88 s, err := t.trans.C(key, num, digits, param)
89 if err != nil {
90 log.Printf("issue translating ordinal key: '%v' error: '%s'", key, err)
91 }
92
93 return s
94 }
95
96 func (t *translator) R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) string {
97
98 s, err := t.trans.R(key, num1, digits1, num2, digits2, param1, param2)
99 if err != nil {
100 log.Printf("issue translating range key: '%v' error: '%s'", key, err)
101 }
102
103 return s
104 }
105
106 func (t *translator) Currency() currency.Type {
107
108
109
110
111
112 switch t.Locale() {
113 case "en":
114 return currency.USD
115 case "fr":
116 return currency.EUR
117 default:
118 return currency.USD
119 }
120 }
121
122 func main() {
123
124 en := en.New()
125 utrans = ut.New(en, en, fr.New())
126 setup()
127
128 tmpls, _ = template.ParseFiles("home.tmpl")
129
130 r := pure.New()
131 r.Use(middleware.LoggingAndRecovery(true), translatorMiddleware)
132 r.Get("/", home)
133
134 log.Println("Running on Port :8080")
135 log.Println("Try me with URL http://localhost:8080/?locale=en")
136 log.Println("and then http://localhost:8080/?locale=fr")
137 http.ListenAndServe(":8080", r.Serve())
138 }
139
140 func home(w http.ResponseWriter, r *http.Request) {
141
142
143 t := r.Context().Value(transKey).(Translator)
144
145 s := struct {
146 Trans Translator
147 Now time.Time
148 PositiveNum float64
149 NegativeNum float64
150 Percent float64
151 }{
152 Trans: t,
153 Now: time.Now(),
154 PositiveNum: 1234576.45,
155 NegativeNum: -35900394.34,
156 Percent: 96.76,
157 }
158
159 if err := tmpls.ExecuteTemplate(w, "home", s); err != nil {
160 log.Fatal(err)
161 }
162 }
163
164 func translatorMiddleware(next http.HandlerFunc) http.HandlerFunc {
165
166 return func(w http.ResponseWriter, r *http.Request) {
167
168
169
170
171 params := r.URL.Query()
172
173 locale := params.Get("locale")
174 var t ut.Translator
175
176 if len(locale) > 0 {
177
178 var found bool
179
180 if t, found = utrans.GetTranslator(locale); found {
181 goto END
182 }
183 }
184
185
186 t, _ = utrans.FindTranslator(pure.AcceptedLanguages(r)...)
187 END:
188
189
190 r = r.WithContext(context.WithValue(r.Context(), transKey, &translator{trans: t, Translator: t.(locales.Translator)}))
191
192 next(w, r)
193 }
194 }
195
196 func setup() {
197
198 err := utrans.Import(ut.FormatJSON, "translations")
199 if err != nil {
200 log.Fatal(err)
201 }
202
203 err = utrans.VerifyTranslations()
204 if err != nil {
205 log.Fatal(err)
206 }
207 }
208
View as plain text