Commit 3712c373f976c51a8ad64e2d941de0298eda8d37
1 parent
de25e1deb6
Exists in
master
better localization detection
Showing
1 changed file
with
23 additions
and
0 deletions
Show diff stats
localization.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "encoding/json" | 4 | "encoding/json" |
5 | "errors" | 5 | "errors" |
6 | "io/ioutil" | 6 | "io/ioutil" |
7 | "net/http" | ||
8 | "strings" | ||
7 | "sync" | 9 | "sync" |
8 | ) | 10 | ) |
9 | 11 | ||
10 | type Dictionary struct { | 12 | type Dictionary struct { |
11 | my sync.Mutex | 13 | my sync.Mutex |
12 | locales map[string]map[string]string | 14 | locales map[string]map[string]string |
13 | supported []string | 15 | supported []string |
14 | defaultLocale string | 16 | defaultLocale string |
15 | } | 17 | } |
16 | 18 | ||
17 | func NewDictionary() *Dictionary { | 19 | func NewDictionary() *Dictionary { |
18 | return &Dictionary{ | 20 | return &Dictionary{ |
19 | locales: map[string]map[string]string{}, | 21 | locales: map[string]map[string]string{}, |
20 | } | 22 | } |
21 | } | 23 | } |
22 | 24 | ||
23 | func (d *Dictionary) AddLocale(loc, filePath string) error { | 25 | func (d *Dictionary) AddLocale(loc, filePath string) error { |
24 | file, err := ioutil.ReadFile(filePath) | 26 | file, err := ioutil.ReadFile(filePath) |
25 | if err != nil { | 27 | if err != nil { |
26 | return err | 28 | return err |
27 | } | 29 | } |
28 | 30 | ||
29 | var data interface{} | 31 | var data interface{} |
30 | err = json.Unmarshal(file, &data) | 32 | err = json.Unmarshal(file, &data) |
31 | if err != nil { | 33 | if err != nil { |
32 | return err | 34 | return err |
33 | } | 35 | } |
34 | 36 | ||
35 | l := map[string]string{} | 37 | l := map[string]string{} |
36 | for k, v := range data.(map[string]interface{}) { | 38 | for k, v := range data.(map[string]interface{}) { |
37 | l[k] = v.(string) | 39 | l[k] = v.(string) |
38 | } | 40 | } |
39 | 41 | ||
40 | mu.Lock() | 42 | mu.Lock() |
41 | defer mu.Unlock() | 43 | defer mu.Unlock() |
42 | d.locales[loc] = l | 44 | d.locales[loc] = l |
43 | d.supported = append(d.supported, loc) | 45 | d.supported = append(d.supported, loc) |
44 | 46 | ||
45 | return nil | 47 | return nil |
46 | } | 48 | } |
47 | 49 | ||
48 | func (d *Dictionary) Translate(loc, key string) string { | 50 | func (d *Dictionary) Translate(loc, key string) string { |
49 | return d.locales[loc][key] | 51 | return d.locales[loc][key] |
50 | } | 52 | } |
51 | 53 | ||
52 | func (d *Dictionary) HasLocale(loc string) bool { | 54 | func (d *Dictionary) HasLocale(loc string) bool { |
53 | for _, v := range d.supported { | 55 | for _, v := range d.supported { |
54 | if v == loc { | 56 | if v == loc { |
55 | return true | 57 | return true |
56 | } | 58 | } |
57 | } | 59 | } |
58 | return false | 60 | return false |
59 | } | 61 | } |
60 | 62 | ||
61 | func (d *Dictionary) SetDefaultLocale(loc string) error { | 63 | func (d *Dictionary) SetDefaultLocale(loc string) error { |
62 | if !d.HasLocale(loc) { | 64 | if !d.HasLocale(loc) { |
63 | return errors.New("dictionary does not contain translations for " + loc) | 65 | return errors.New("dictionary does not contain translations for " + loc) |
64 | } | 66 | } |
65 | d.defaultLocale = loc | 67 | d.defaultLocale = loc |
66 | return nil | 68 | return nil |
67 | } | 69 | } |
68 | 70 | ||
69 | func (d *Dictionary) GetDefaultLocale() string { | 71 | func (d *Dictionary) GetDefaultLocale() string { |
70 | return d.defaultLocale | 72 | return d.defaultLocale |
71 | } | 73 | } |
74 | |||
75 | func (d *Dictionary) GetBestMatchLocale(req *http.Request) (best string) { | ||
76 | accepted := d.parseAcceptedLanguageHeader(req) | ||
77 | best = accepted[0] | ||
78 | return | ||
79 | } | ||
80 | |||
81 | func (d *Dictionary) parseAcceptedLanguageHeader(req *http.Request) (langs []string) { | ||
82 | a := req.Header.Get("Accepted-Language") | ||
83 | if a == "" { | ||
84 | langs = append(langs, d.GetDefaultLocale()) | ||
85 | return | ||
86 | } | ||
87 | |||
88 | parts := strings.Split(a, ",") | ||
89 | for _, p := range parts { | ||
90 | langs = append(langs, p) | ||
91 | } | ||
92 | |||
93 | return | ||
94 | } | ||
72 | 95 |