From 85eeab8c193a183badc291c750ac1b2653aee98a Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 9 Feb 2022 14:48:56 +0800 Subject: [PATCH] + langs support --- app/app.go | 75 +++++++++++++++++++ app/app_test.go | 15 ++++ data/bindata.go | 75 ++++++++++++------- lang/lang.go | 1 - share/lang.go | 6 -- share/types.go | 2 + tests/app.json | 1 + tests/langs/en-US.json | 4 + .../locales/en.json => xiang/langs/en-US.json | 2 +- 9 files changed, 148 insertions(+), 33 deletions(-) create mode 100644 app/app_test.go delete mode 100644 lang/lang.go delete mode 100644 share/lang.go create mode 100644 tests/langs/en-US.json rename tests/locales/en.json => xiang/langs/en-US.json (68%) diff --git a/app/app.go b/app/app.go index c18b2ad2..31e927f3 100644 --- a/app/app.go +++ b/app/app.go @@ -1,8 +1,14 @@ package app import ( + "fmt" + "os" + "path/filepath" + "strings" + jsoniter "github.com/json-iterator/go" "github.com/yaoapp/kun/exception" + "github.com/yaoapp/kun/log" "github.com/yaoapp/kun/maps" "github.com/yaoapp/yao/config" "github.com/yaoapp/yao/data" @@ -10,10 +16,20 @@ import ( "github.com/yaoapp/yao/xfs" ) +// langs 语言包 +var langs = map[string]map[string]string{} + // Load 加载应用信息 func Load(cfg config.Config) { Init(cfg) LoadInfo(cfg.Root) + LoadLang(cfg) + + lang := strings.ToLower(share.App.Lang) + share.App.L = map[string]string{} + if l, has := langs[lang]; has { + share.App.L = l + } } // Init 应用初始化 @@ -85,6 +101,65 @@ func LoadInfo(root string) { share.App = info } +// LoadLang 加载语言包 +func LoadLang(cfg config.Config) error { + + var defaults = []share.Script{} + if os.Getenv("YAO_DEV") != "" { + defaults = share.GetFilesFS(filepath.Join(os.Getenv("YAO_DEV"), "xiang", "langs"), ".json") + } else { + defaults = share.GetFilesBin("/xiang/langs", ".json") + } + + for _, lang := range defaults { + content := lang.Content + name := strings.ToLower(lang.Type) // 这个读取函数需要优化 + lang := map[string]string{} + err := jsoniter.Unmarshal(content, &lang) + if err != nil { + log.With(log.F{"name": name, "content": content}).Error(err.Error()) + } + langs[name] = lang + } + + if share.BUILDIN { + return LoadLangBuildIn("langs") + } + return LoadLangFrom(filepath.Join(cfg.Root, "langs")) +} + +// LoadLangBuildIn 从制品中读取 +func LoadLangBuildIn(dir string) error { + return nil +} + +// LoadLangFrom 从特定目录加载 +func LoadLangFrom(dir string) error { + + if share.DirNotExists(dir) { + return fmt.Errorf("%s does not exists", dir) + } + + err := share.Walk(dir, ".json", func(root, filename string) { + name := strings.ToLower(share.SpecName(root, filename)) + content := share.ReadFile(filename) + lang := map[string]string{} + err := jsoniter.Unmarshal(content, &lang) + if err != nil { + log.With(log.F{"root": root, "file": filename}).Error(err.Error()) + } + if _, has := langs[name]; !has { + langs[name] = map[string]string{} + } + for src, dst := range lang { + langs[name][src] = dst + } + }) + + return err + +} + // defaultInfo 读取默认应用信息 func defaultInfo() share.AppInfo { info := share.AppInfo{ diff --git a/app/app_test.go b/app/app_test.go new file mode 100644 index 00000000..05305342 --- /dev/null +++ b/app/app_test.go @@ -0,0 +1,15 @@ +package app + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/yaoapp/yao/config" + "github.com/yaoapp/yao/share" +) + +func TestLoad(t *testing.T) { + Load(config.Conf) + assert.Equal(t, "Yao", share.App.L["Yao"]) + assert.Equal(t, "Xiang", share.App.L["象传"]) +} diff --git a/data/bindata.go b/data/bindata.go index 158803e6..05ec27dd 100644 --- a/data/bindata.go +++ b/data/bindata.go @@ -18,6 +18,7 @@ // .tmp/data/xiang/flows/README.md // .tmp/data/xiang/flows/menu.flow.json // .tmp/data/xiang/flows/table/get.flow.json +// .tmp/data/xiang/langs/en-US.json // .tmp/data/xiang/models/README.md // .tmp/data/xiang/models/menu.json // .tmp/data/xiang/models/user.json @@ -203,7 +204,7 @@ func uiIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "ui/index.html", size: 12, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "ui/index.html", size: 12, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -223,7 +224,7 @@ func xiangApisReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -243,7 +244,7 @@ func xiangApisChartHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -263,7 +264,7 @@ func xiangApisImportHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/import.http.json", size: 1676, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/import.http.json", size: 1676, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -283,7 +284,7 @@ func xiangApisPageHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -303,7 +304,7 @@ func xiangApisStorageHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/storage.http.json", size: 1092, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/storage.http.json", size: 1092, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -323,7 +324,7 @@ func xiangApisTableHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/table.http.json", size: 3196, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/table.http.json", size: 3196, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -343,7 +344,7 @@ func xiangApisUserHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -363,7 +364,7 @@ func xiangApisXiangHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/apis/xiang.http.json", size: 1239, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/apis/xiang.http.json", size: 1239, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -383,7 +384,7 @@ func xiangDataAppJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/app.json", size: 245, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/data/app.json", size: 245, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -403,7 +404,7 @@ func xiangDataIcons404Png() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -423,7 +424,7 @@ func xiangDataIconsIconIcns() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/icon.icns", size: 75636, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/data/icons/icon.icns", size: 75636, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -443,7 +444,7 @@ func xiangDataIconsIconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/icon.ico", size: 31310, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/data/icons/icon.ico", size: 31310, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -463,7 +464,7 @@ func xiangDataIconsIconPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/icons/icon.png", size: 22420, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/data/icons/icon.png", size: 22420, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -483,7 +484,7 @@ func xiangDataIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/data/index.html", size: 302, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/data/index.html", size: 302, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -503,7 +504,7 @@ func xiangFlowsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -523,7 +524,7 @@ func xiangFlowsMenuFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -543,7 +544,27 @@ func xiangFlowsTableGetFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/flows/table/get.flow.json", size: 541, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/flows/table/get.flow.json", size: 541, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _xiangLangsEnUsJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xaa\xe6\x52\x50\x50\x7a\xb1\x71\xe1\x93\x3d\x0b\x94\xac\x14\x94\x22\x32\x13\xf3\xd2\x95\x74\x10\x82\x4f\x77\x4d\x79\x3e\x65\xc5\xd3\x3d\x53\x9f\x4d\xee\x03\x29\x88\x4c\xcc\x57\x70\x2c\x28\x50\x70\xcd\x4b\xcf\xcc\x4b\x55\xe2\xaa\xe5\x02\x04\x00\x00\xff\xff\x7e\x77\x1c\x72\x42\x00\x00\x00") + +func xiangLangsEnUsJsonBytes() ([]byte, error) { + return bindataRead( + _xiangLangsEnUsJson, + "xiang/langs/en-US.json", + ) +} + +func xiangLangsEnUsJson() (*asset, error) { + bytes, err := xiangLangsEnUsJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "xiang/langs/en-US.json", size: 66, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -563,7 +584,7 @@ func xiangModelsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -583,7 +604,7 @@ func xiangModelsMenuJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/models/menu.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/models/menu.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -603,7 +624,7 @@ func xiangModelsUserJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/models/user.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/models/user.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -623,7 +644,7 @@ func xiangModelsWorkflowModJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/models/workflow.mod.json", size: 3333, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/models/workflow.mod.json", size: 3333, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -643,7 +664,7 @@ func xiangTablesReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -663,7 +684,7 @@ func xiangTablesMenuJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/tables/menu.json", size: 10382, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/tables/menu.json", size: 10382, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -683,7 +704,7 @@ func xiangTablesUserJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xiang/tables/user.json", size: 1422, mode: os.FileMode(420), modTime: time.Unix(1644337051, 0)} + info := bindataFileInfo{name: "xiang/tables/user.json", size: 1422, mode: os.FileMode(420), modTime: time.Unix(1644389315, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -758,6 +779,7 @@ var _bindata = map[string]func() (*asset, error){ "xiang/flows/README.md": xiangFlowsReadmeMd, "xiang/flows/menu.flow.json": xiangFlowsMenuFlowJson, "xiang/flows/table/get.flow.json": xiangFlowsTableGetFlowJson, + "xiang/langs/en-US.json": xiangLangsEnUsJson, "xiang/models/README.md": xiangModelsReadmeMd, "xiang/models/menu.json": xiangModelsMenuJson, "xiang/models/user.json": xiangModelsUserJson, @@ -839,6 +861,9 @@ var _bintree = &bintree{nil, map[string]*bintree{ "get.flow.json": {xiangFlowsTableGetFlowJson, map[string]*bintree{}}, }}, }}, + "langs": {nil, map[string]*bintree{ + "en-US.json": {xiangLangsEnUsJson, map[string]*bintree{}}, + }}, "models": {nil, map[string]*bintree{ "README.md": {xiangModelsReadmeMd, map[string]*bintree{}}, "menu.json": {xiangModelsMenuJson, map[string]*bintree{}}, diff --git a/lang/lang.go b/lang/lang.go deleted file mode 100644 index 48e87f86..00000000 --- a/lang/lang.go +++ /dev/null @@ -1 +0,0 @@ -package lang diff --git a/share/lang.go b/share/lang.go deleted file mode 100644 index 4f6b9b37..00000000 --- a/share/lang.go +++ /dev/null @@ -1,6 +0,0 @@ -package share - -// Langs 多语言包 -var Langs = map[string]string{ - "象传应用引擎": "Yao App Engine", -} diff --git a/share/types.go b/share/types.go index e854f589..2f6253c9 100644 --- a/share/types.go +++ b/share/types.go @@ -71,6 +71,8 @@ type Page struct { // AppInfo 应用信息 type AppInfo struct { Name string `json:"name,omitempty"` + Lang string `json:"lang,omitempty"` + L map[string]string `json:"-"` // 应用的语言包 Short string `json:"short,omitempty"` Version string `json:"version,omitempty"` Description string `json:"description,omitempty"` diff --git a/tests/app.json b/tests/app.json index 3f642d30..56437a1e 100644 --- a/tests/app.json +++ b/tests/app.json @@ -2,6 +2,7 @@ "name": "象传应用", "short": "象传", "description": "象传应用后台", + "lang": "en-US", "option": { "index": "/table/service" }, diff --git a/tests/langs/en-US.json b/tests/langs/en-US.json new file mode 100644 index 00000000..54d43606 --- /dev/null +++ b/tests/langs/en-US.json @@ -0,0 +1,4 @@ +{ + "Yao": "Yao", + "象传应用引擎": "Yao App Engine Over load" +} diff --git a/tests/locales/en.json b/xiang/langs/en-US.json similarity index 68% rename from tests/locales/en.json rename to xiang/langs/en-US.json index 0eeffd75..2c9fd953 100644 --- a/tests/locales/en.json +++ b/xiang/langs/en-US.json @@ -1,4 +1,4 @@ { - "Yao": "Yao", + "象传": "Xiang", "象传应用引擎": "Yao App Engine" }