[add] language pack support for model
This commit is contained in:
parent
8d88682967
commit
2349d17d99
15 changed files with 143 additions and 125 deletions
130
app/app.go
130
app/app.go
|
|
@ -1,35 +1,32 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
l "github.com/yaoapp/gou/lang"
|
||||
"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"
|
||||
"github.com/yaoapp/yao/lang"
|
||||
"github.com/yaoapp/yao/share"
|
||||
"github.com/yaoapp/yao/xfs"
|
||||
)
|
||||
|
||||
// langs 语言包
|
||||
var langs = map[string]map[string]string{}
|
||||
|
||||
// Load 加载应用信息
|
||||
// Load Application
|
||||
func Load(cfg config.Config) {
|
||||
Init(cfg)
|
||||
LoadInfo(cfg.Root)
|
||||
LoadLang(cfg)
|
||||
|
||||
lang := strings.ToLower(share.App.Lang)
|
||||
// Load language packs
|
||||
lang.Load(cfg)
|
||||
|
||||
// Set language pack
|
||||
share.App.L = map[string]string{}
|
||||
if l, has := langs[lang]; has {
|
||||
share.App.L = l
|
||||
if l.Default != nil {
|
||||
share.App.L = l.Default.Global
|
||||
}
|
||||
|
||||
// Load Info
|
||||
LoadInfo(cfg.Root)
|
||||
|
||||
}
|
||||
|
||||
// L 语言包
|
||||
|
|
@ -40,49 +37,6 @@ func L(word string) string {
|
|||
return word
|
||||
}
|
||||
|
||||
// Init 应用初始化
|
||||
func Init(cfg config.Config) {
|
||||
|
||||
// // UI文件目录
|
||||
// if _, err := os.Stat(cfg.RootUI); os.IsNotExist(err) {
|
||||
// err := os.MkdirAll(cfg.RootUI, os.ModePerm)
|
||||
// if err != nil {
|
||||
// xlog.Printf("创建目录失败(%s) %s", cfg.RootUI, err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
|
||||
// content, err := data.Asset("xiang/data/index.html")
|
||||
// if err != nil {
|
||||
// xlog.Printf("读取文件失败(%s) %s", cfg.RootUI, err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
|
||||
// err = ioutil.WriteFile(filepath.Join(cfg.RootUI, "/index.html"), content, os.ModePerm)
|
||||
// if err != nil {
|
||||
// xlog.Printf("复制默认文件失败(%s) %s", cfg.RootUI, err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 数据库目录
|
||||
// if _, err := os.Stat(cfg.RootDB); os.IsNotExist(err) {
|
||||
// err := os.MkdirAll(cfg.RootDB, os.ModePerm)
|
||||
// if err != nil {
|
||||
// xlog.Printf("创建目录失败(%s) %s", cfg.RootDB, err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 文件数据目录
|
||||
// if _, err := os.Stat(cfg.RootData); os.IsNotExist(err) {
|
||||
// err := os.MkdirAll(cfg.RootData, os.ModePerm)
|
||||
// if err != nil {
|
||||
// xlog.Printf("创建目录失败(%s) %s", cfg.RootData, err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// LoadInfo 应用信息
|
||||
func LoadInfo(root string) {
|
||||
info := defaultInfo()
|
||||
|
|
@ -106,71 +60,15 @@ func LoadInfo(root string) {
|
|||
info.Icons.Set("png", xfs.Encode(fs.MustReadFile("/yao/icons/icon.png")))
|
||||
}
|
||||
|
||||
info.L = share.App.L
|
||||
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"), "yao"), ".json")
|
||||
} else {
|
||||
defaults = share.GetFilesBin("yao", ".json")
|
||||
}
|
||||
|
||||
for _, lang := range defaults {
|
||||
if lang.Type != "langs" {
|
||||
continue
|
||||
}
|
||||
content := lang.Content
|
||||
name := strings.ToLower(lang.Name) // 这个读取函数需要优化
|
||||
lang := map[string]string{}
|
||||
err := jsoniter.Unmarshal(content, &lang)
|
||||
if err != nil {
|
||||
log.With(log.F{"name": name}).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{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -9,7 +10,8 @@ import (
|
|||
)
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
os.Setenv("YAO_LANG", "zh-cn")
|
||||
Load(config.Conf)
|
||||
assert.Equal(t, "Yao", share.App.L["Yao"])
|
||||
assert.Equal(t, "Xiang", share.App.L["象传"])
|
||||
assert.Equal(t, "YAO", share.App.L["Yao"])
|
||||
assert.Equal(t, "象传", share.App.L["Xiang"])
|
||||
}
|
||||
|
|
|
|||
36
lang/lang.go
Normal file
36
lang/lang.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package lang
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/yaoapp/gou/lang"
|
||||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/yao/config"
|
||||
)
|
||||
|
||||
func init() {
|
||||
lang.RegisterWidget("tables", "table")
|
||||
lang.RegisterWidget("charts", "chart")
|
||||
lang.RegisterWidget("kanban", "kanban")
|
||||
}
|
||||
|
||||
// Load language packs
|
||||
func Load(cfg config.Config) error {
|
||||
root := filepath.Join(cfg.Root, "langs")
|
||||
err := lang.Load(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := os.Getenv("YAO_LANG")
|
||||
if name != "" {
|
||||
if _, has := lang.Dicts[name]; !has {
|
||||
log.Error("The language pack %s does not found", name)
|
||||
return nil
|
||||
}
|
||||
lang.Pick(name).AsDefault()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
16
lang/lang_test.go
Normal file
16
lang/lang_test.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package lang
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/gou/lang"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/share"
|
||||
)
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
share.DBConnect(config.Conf.DB)
|
||||
Load(config.Conf)
|
||||
assert.Len(t, lang.Dicts, 2)
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/gou/lang"
|
||||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/share"
|
||||
|
|
@ -31,7 +32,14 @@ func LoadFrom(dir string, prefix string) error {
|
|||
_, err := gou.LoadModelReturn(string(content), name)
|
||||
if err != nil {
|
||||
log.With(log.F{"root": root, "file": filename}).Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Apply the language pack
|
||||
if lang.Default != nil {
|
||||
lang.Default.Apply(gou.Models[name])
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/lang"
|
||||
"github.com/yaoapp/yao/share"
|
||||
)
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
|
||||
os.Setenv("YAO_LANG", "zh-hk")
|
||||
lang.Load(config.Conf)
|
||||
share.DBConnect(config.Conf.DB)
|
||||
|
||||
gou.Models = make(map[string]*gou.Model)
|
||||
Load(config.Conf)
|
||||
LoadFrom("not a path", "404.")
|
||||
|
|
@ -23,5 +29,9 @@ func check(t *testing.T) {
|
|||
for key := range gou.Models {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
assert.Equal(t, 10, len(keys))
|
||||
assert.Equal(t, 11, len(keys))
|
||||
|
||||
demo := gou.Select("demo")
|
||||
assert.Equal(t, demo.MetaData.Name, "演示")
|
||||
assert.Equal(t, demo.Columns["action"].Label, "動作")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,7 @@ type Page struct {
|
|||
// AppInfo 应用信息
|
||||
type AppInfo struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Lang string `json:"lang,omitempty"`
|
||||
L map[string]string `json:"-"` // 应用的语言包
|
||||
L map[string]string `json:"-"`
|
||||
Short string `json:"short,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Yao": "Yao",
|
||||
"象传应用引擎": "Yao App Engine Over load"
|
||||
}
|
||||
1
tests/langs/zh-cn/flows/hello.flow.yml
Normal file
1
tests/langs/zh-cn/flows/hello.flow.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
Latest: 最新信息
|
||||
7
tests/langs/zh-cn/global.yml
Normal file
7
tests/langs/zh-cn/global.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Demo: 演示
|
||||
Phone: 电话号码
|
||||
ZipCode: 邮政编码
|
||||
Uptime: 更新时间
|
||||
Action: 动作
|
||||
Yao: YAO
|
||||
Xiang: 象传
|
||||
1
tests/langs/zh-cn/models/demo.mod.yml
Normal file
1
tests/langs/zh-cn/models/demo.mod.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
SN: 编码
|
||||
1
tests/langs/zh-hk/flows/hello.flow.yml
Normal file
1
tests/langs/zh-hk/flows/hello.flow.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
Latest: 最新信息
|
||||
7
tests/langs/zh-hk/global.yml
Normal file
7
tests/langs/zh-hk/global.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Demo: 演示
|
||||
Phone: 電話號碼
|
||||
ZipCode: 郵政編碼
|
||||
Uptime: 更新時間
|
||||
Action: 動作
|
||||
Yao: YAO
|
||||
Xiang: 像傳
|
||||
1
tests/langs/zh-hk/models/demo.mod.yml
Normal file
1
tests/langs/zh-hk/models/demo.mod.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
SN: 編碼
|
||||
35
tests/models/demo.mod.json
Normal file
35
tests/models/demo.mod.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "::Demo",
|
||||
"connector": "trace",
|
||||
"table": { "name": "user_trace", "comment": "::Demo" },
|
||||
"columns": [
|
||||
{ "label": "ID", "name": "id", "type": "ID" },
|
||||
{
|
||||
"label": "::SN",
|
||||
"name": "user_sn",
|
||||
"type": "string",
|
||||
"length": 42,
|
||||
"index": true
|
||||
},
|
||||
{
|
||||
"label": "::Uptime",
|
||||
"name": "uptime",
|
||||
"type": "datetime",
|
||||
"index": true
|
||||
},
|
||||
{
|
||||
"label": "::Action",
|
||||
"name": "action",
|
||||
"type": "enum",
|
||||
"option": ["进入", "离开"],
|
||||
"index": true
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"name": "user_sn_action_unique",
|
||||
"type": "unique",
|
||||
"columns": ["user_sn", "action"]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue