Commit 3712c373f976c51a8ad64e2d941de0298eda8d37

Authored by Marko Tikvić
1 parent de25e1deb6
Exists in master

better localization detection

Showing 1 changed file with 23 additions and 0 deletions   Show diff stats
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