Blame view
localization.go
2.91 KB
9933169c8 localization support |
1 2 3 4 |
package webutility import ( "encoding/json" |
2b62f61cc minor changes |
5 |
"fmt" |
9933169c8 localization support |
6 |
"io/ioutil" |
89f45d7aa GetBestMatchLocal... |
7 |
"net/http" |
e97375e4d strip file extension |
8 |
"path" |
715bb6ad8 parsing of accept... |
9 |
"strconv" |
3712c373f better localizati... |
10 |
"strings" |
3fffcb954 removed old http API |
11 |
"sync" |
9933169c8 localization support |
12 |
) |
707782344 lint; vet |
13 |
// Dictionary ... |
f84e7607d added dictionary;... |
14 |
type Dictionary struct { |
3fffcb954 removed old http API |
15 |
my sync.Mutex |
a205e8f40 changes |
16 17 18 |
locales map[string]map[string]string supported []string defaultLocale string |
f84e7607d added dictionary;... |
19 |
} |
707782344 lint; vet |
20 |
// NewDictionary ... |
2b62f61cc minor changes |
21 22 |
func NewDictionary() *Dictionary { return &Dictionary{ |
f84e7607d added dictionary;... |
23 24 25 |
locales: map[string]map[string]string{}, } } |
9933169c8 localization support |
26 |
|
707782344 lint; vet |
27 |
// AddTranslations ... |
0207726c4 improved localiza... |
28 29 |
func (d *Dictionary) AddTranslations(directory string) error { files, err := ioutil.ReadDir(directory) |
9933169c8 localization support |
30 31 32 |
if err != nil { return err } |
0207726c4 improved localiza... |
33 34 |
for _, fileInfo := range files { fName := fileInfo.Name() |
5bba6f75f bug fix |
35 |
path := directory + "/" + fName |
0207726c4 improved localiza... |
36 37 38 39 |
file, err := ioutil.ReadFile(path) if err != nil { return err } |
9933169c8 localization support |
40 |
|
e97375e4d strip file extension |
41 |
loc := stripFileExtension(fName) |
0207726c4 improved localiza... |
42 |
|
0207726c4 improved localiza... |
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
var data interface{} err = json.Unmarshal(file, &data) if err != nil { return err } l := map[string]string{} for k, v := range data.(map[string]interface{}) { l[k] = v.(string) } mu.Lock() defer mu.Unlock() d.locales[loc] = l d.supported = append(d.supported, loc) } |
9933169c8 localization support |
59 |
|
2b62f61cc minor changes |
60 61 |
if d.defaultLocale == "" && len(d.supported) > 0 { d.defaultLocale = d.supported[0] |
715bb6ad8 parsing of accept... |
62 |
} |
9933169c8 localization support |
63 64 |
return nil } |
707782344 lint; vet |
65 |
// GetBestMatchLocale ... |
89f45d7aa GetBestMatchLocal... |
66 67 |
func (d *Dictionary) GetBestMatchLocale(req *http.Request) (best string) { accepted := d.parseAcceptedLanguages(req.Header.Get("Accept-Language")) |
715bb6ad8 parsing of accept... |
68 |
|
707782344 lint; vet |
69 |
for i := range accepted { |
89f45d7aa GetBestMatchLocal... |
70 71 72 |
if accepted[i].Code == "*" { return d.defaultLocale } |
707782344 lint; vet |
73 |
for j := range d.supported { |
715bb6ad8 parsing of accept... |
74 75 76 77 78 79 80 |
if accepted[i].Code == d.supported[j] { return d.supported[j] } } } return d.defaultLocale |
0207726c4 improved localiza... |
81 |
} |
707782344 lint; vet |
82 |
// Translate ... |
f84e7607d added dictionary;... |
83 84 85 |
func (d *Dictionary) Translate(loc, key string) string { return d.locales[loc][key] } |
707782344 lint; vet |
86 |
// SetDefaultLocale ... |
2b62f61cc minor changes |
87 88 89 90 91 92 93 94 95 96 97 |
func (d *Dictionary) SetDefaultLocale(loc string) error { if !d.contains(loc) { return fmt.Errorf("locale file not loaded: %s", loc) } d.defaultLocale = loc return nil } func (d *Dictionary) contains(loc string) bool { |
a205e8f40 changes |
98 99 |
for _, v := range d.supported { if v == loc { |
f84e7607d added dictionary;... |
100 101 102 103 |
return true } } return false |
9933169c8 localization support |
104 |
} |
a205e8f40 changes |
105 |
|
707782344 lint; vet |
106 |
// LangWeight ... |
715bb6ad8 parsing of accept... |
107 108 109 |
type LangWeight struct { Code string Weight float64 |
a205e8f40 changes |
110 |
} |
715bb6ad8 parsing of accept... |
111 112 113 114 |
func (d *Dictionary) parseAcceptedLanguages(accepted string) (langs []LangWeight) { if accepted == "" { langs = append(langs, LangWeight{Code: d.defaultLocale, Weight: 1.0}) return langs |
3712c373f better localizati... |
115 |
} |
707782344 lint; vet |
116 117 |
var code string var weight float64 |
715bb6ad8 parsing of accept... |
118 |
parts := strings.Split(accepted, ",") |
707782344 lint; vet |
119 |
for i := range parts { |
89f45d7aa GetBestMatchLocal... |
120 |
parts[i] = strings.Trim(parts[i], " ") |
715bb6ad8 parsing of accept... |
121 |
|
715bb6ad8 parsing of accept... |
122 123 124 125 126 127 128 129 130 131 |
cw := strings.Split(parts[i], ";") paramCount := len(cw) if paramCount == 1 { // default weight of 1 code = cw[0] weight = 1.0 } else if paramCount == 2 { // parse weight code = cw[0] |
89f45d7aa GetBestMatchLocal... |
132 |
weight, _ = strconv.ParseFloat(cw[1][2:], 64) |
715bb6ad8 parsing of accept... |
133 134 |
} |
715bb6ad8 parsing of accept... |
135 |
langs = append(langs, LangWeight{Code: code, Weight: weight}) |
3712c373f better localizati... |
136 |
} |
89f45d7aa GetBestMatchLocal... |
137 |
// TODO(marko): sort langs by weights? |
715bb6ad8 parsing of accept... |
138 139 |
return langs |
3712c373f better localizati... |
140 |
} |
0207726c4 improved localiza... |
141 142 |
func stripFileExtension(full string) (stripped string) { |
e97375e4d strip file extension |
143 144 145 |
extension := path.Ext(full) stripped = strings.TrimSuffix(full, extension) return stripped |
0207726c4 improved localiza... |
146 |
} |