package g import ( "encoding/json" "errors" "fmt" "io/ioutil" "os" "path/filepath" ) const ( DEF_LANG = "en" DEF_LANG_EXT = ".json" ) var ( defaultLang *Lang ErrLangNoExists = errors.New("language path not exists") ) func SetDefaultLang(l *Lang) { defaultLang = l } type Lang struct { baseDir string // lang file base dir words map[string]map[string]string // single lang words } func NewLang(dir string) *Lang { l := &Lang{ baseDir: dir, words: make(map[string]map[string]string), } l.Reload() return l } func (self *Lang) Get(k string, useLang ...string) string { l := DEF_LANG if len(useLang) > 0 { l = useLang[0] } kv, ok := self.words[l] if !ok { fmt.Println("no language:", l) return "" } if word, ok := kv[k]; ok { return word } fmt.Printf("no key<%v> for lang<%v>\n", k, l) return "" } func (self *Lang) Reload() { self.scan(filepath.Join(self.baseDir)) } func (self *Lang) scan(jsDir string) { self.words = make(map[string]map[string]string) err := filepath.Walk(jsDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { self.words[info.Name()] = make(map[string]string) } if filepath.Ext(path) != DEF_LANG_EXT { return nil } langDir := filepath.Base(filepath.Dir(path)) langKv, ok := self.words[langDir] if !ok { return ErrLangNoExists } fh, err := os.Open(path) if err != nil { return err } defer fh.Close() data, err := ioutil.ReadAll(fh) if err != nil { return err } partial := map[string]string{} err = json.Unmarshal(data, &partial) if err != nil { return err } for k, v := range partial { langKv[k] = v } return nil }) if err != nil { fmt.Println("scan() error:", err) } } func T(k string, useLang ...string) string { if defaultLang != nil { return defaultLang.Get(k, useLang...) } return "" }