[add] language pack support for page
This commit is contained in:
parent
850e4dacc5
commit
6283b6e34c
10 changed files with 281 additions and 9 deletions
|
|
@ -40,4 +40,6 @@ func check(t *testing.T) {
|
|||
filters := lang.Page.Layout["filters"].([]interface{})
|
||||
begin := filters[0].(map[string]interface{})
|
||||
assert.Equal(t, "開始時間", begin["name"])
|
||||
|
||||
assert.Equal(t, "請選擇開始時間", lang.Filters["開始時間"].Input.Props["placeholder"])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ func (chart *Chart) Lang(trans func(widget string, inst string, value *string) b
|
|||
trans(widget, inst, &chart.Page.Primary)
|
||||
transMap(widget, inst, chart.Page.Layout, trans)
|
||||
chart.Output = transAny(widget, inst, chart.Output, trans)
|
||||
|
||||
// Filters
|
||||
for name, filter := range chart.Filters {
|
||||
new := name
|
||||
trans(widget, inst, &new)
|
||||
trans(widget, inst, &filter.Label)
|
||||
delete(chart.Filters, name)
|
||||
|
||||
// Props
|
||||
transMap(widget, inst, filter.Input.Props, trans)
|
||||
chart.Filters[new] = filter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func transAny(widget string, inst string, input interface{}, trans func(widget string, inst string, value *string) bool) interface{} {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ import (
|
|||
func init() {
|
||||
lang.RegisterWidget("tables", "table")
|
||||
lang.RegisterWidget("charts", "chart")
|
||||
lang.RegisterWidget("kanban", "kanban")
|
||||
lang.RegisterWidget("kanban", "page")
|
||||
lang.RegisterWidget("screen", "page")
|
||||
lang.RegisterWidget("pages", "page")
|
||||
}
|
||||
|
||||
// Load language packs
|
||||
|
|
|
|||
125
page/lang.go
Normal file
125
page/lang.go
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
package page
|
||||
|
||||
// Lang for applying a language pack
|
||||
func (page *Page) Lang(trans func(widget string, inst string, value *string) bool) {
|
||||
inst := page.Flow.Name
|
||||
widget := "page"
|
||||
|
||||
trans(widget, inst, &page.Name)
|
||||
trans(widget, inst, &page.Label)
|
||||
trans(widget, inst, &page.Description)
|
||||
trans(widget, inst, &page.Page.Primary)
|
||||
transMap(widget, inst, page.Page.Layout, trans)
|
||||
page.Output = transAny(widget, inst, page.Output, trans)
|
||||
|
||||
// Filters
|
||||
for name, filter := range page.Filters {
|
||||
new := name
|
||||
trans(widget, inst, &new)
|
||||
trans(widget, inst, &filter.Label)
|
||||
delete(page.Filters, name)
|
||||
|
||||
// Props
|
||||
transMap(widget, inst, filter.Input.Props, trans)
|
||||
page.Filters[new] = filter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func transAny(widget string, inst string, input interface{}, trans func(widget string, inst string, value *string) bool) interface{} {
|
||||
switch input.(type) {
|
||||
case []interface{}:
|
||||
values := input.([]interface{})
|
||||
transArr(widget, inst, values, trans)
|
||||
input = values
|
||||
break
|
||||
|
||||
case map[string]interface{}:
|
||||
values := input.(map[string]interface{})
|
||||
for name, value := range values {
|
||||
new := name
|
||||
newValue := value
|
||||
|
||||
switch value.(type) {
|
||||
case string:
|
||||
val := value.(string)
|
||||
trans(widget, inst, &val)
|
||||
newValue = val
|
||||
break
|
||||
|
||||
case []interface{}:
|
||||
vals := value.([]interface{})
|
||||
transArr(widget, inst, vals, trans)
|
||||
newValue = vals
|
||||
break
|
||||
|
||||
case map[string]interface{}:
|
||||
vals := value.(map[string]interface{})
|
||||
transMap(widget, inst, vals, trans)
|
||||
newValue = vals
|
||||
break
|
||||
}
|
||||
|
||||
trans(widget, inst, &new)
|
||||
delete(values, name)
|
||||
values[new] = newValue
|
||||
}
|
||||
input = values
|
||||
break
|
||||
}
|
||||
|
||||
return input
|
||||
}
|
||||
|
||||
func transMap(widget string, inst string, values map[string]interface{}, trans func(widget string, inst string, value *string) bool) {
|
||||
for key, value := range values {
|
||||
|
||||
switch value.(type) {
|
||||
|
||||
case string:
|
||||
v := value.(string)
|
||||
trans(widget, inst, &v)
|
||||
values[key] = v
|
||||
break
|
||||
|
||||
case []interface{}:
|
||||
v := value.([]interface{})
|
||||
transArr(widget, inst, v, trans)
|
||||
values[key] = v
|
||||
break
|
||||
|
||||
case map[string]interface{}:
|
||||
v := value.(map[string]interface{})
|
||||
transMap(widget, inst, v, trans)
|
||||
values[key] = v
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func transArr(widget string, inst string, values []interface{}, trans func(widget string, inst string, value *string) bool) {
|
||||
for key, value := range values {
|
||||
switch value.(type) {
|
||||
|
||||
case string:
|
||||
v := value.(string)
|
||||
trans(widget, inst, &v)
|
||||
values[key] = v
|
||||
break
|
||||
|
||||
case []interface{}:
|
||||
v := value.([]interface{})
|
||||
transArr(widget, inst, v, trans)
|
||||
values[key] = v
|
||||
break
|
||||
|
||||
case map[string]interface{}:
|
||||
v := value.(map[string]interface{})
|
||||
transMap(widget, inst, v, trans)
|
||||
values[key] = v
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
13
page/page.go
13
page/page.go
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/gou/lang"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/yao/config"
|
||||
|
|
@ -24,15 +25,15 @@ func Load(cfg config.Config) error {
|
|||
|
||||
var errs error = nil
|
||||
if err := LoadFrom(path.Join(cfg.Root, "/kanban"), ""); err != nil {
|
||||
log.Trace("load kanban error: %s ", err.Error())
|
||||
// log.Trace("load kanban error: %s ", err.Error())
|
||||
errs = err
|
||||
}
|
||||
if err := LoadFrom(path.Join(cfg.Root, "/screen"), ""); err != nil {
|
||||
log.Trace("load screen error: %s", err.Error())
|
||||
// log.Trace("load screen error: %s", err.Error())
|
||||
errs = err
|
||||
}
|
||||
if err := LoadFrom(path.Join(cfg.Root, "/pages"), ""); err != nil {
|
||||
log.Trace("load screen error: %s", err.Error())
|
||||
// log.Trace("load screen error: %s", err.Error())
|
||||
errs = err
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +94,12 @@ func LoadPage(source []byte, name string) (*Page, error) {
|
|||
page.Prepare()
|
||||
page.SetupAPIs()
|
||||
Pages[name] = page
|
||||
|
||||
// Apply a language pack
|
||||
if lang.Default != nil {
|
||||
lang.Default.Apply(Pages[name])
|
||||
}
|
||||
|
||||
return page, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
package page
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/lang"
|
||||
"github.com/yaoapp/yao/model"
|
||||
"github.com/yaoapp/yao/query"
|
||||
"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)
|
||||
model.Load(config.Conf)
|
||||
query.Load(config.Conf)
|
||||
|
|
@ -25,5 +31,15 @@ func check(t *testing.T) {
|
|||
for key := range Pages {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
assert.Equal(t, 1, len(keys))
|
||||
assert.Equal(t, 2, len(keys))
|
||||
|
||||
lang := Pages["lang"]
|
||||
output := lang.Output.(map[string]interface{})
|
||||
assert.Equal(t, "{{$in}}", output["參數"])
|
||||
|
||||
filters := lang.Page.Layout["filters"].([]interface{})
|
||||
begin := filters[0].(map[string]interface{})
|
||||
assert.Equal(t, "開始時間", begin["name"])
|
||||
|
||||
assert.Equal(t, "請選擇開始時間", lang.Filters["開始時間"].Input.Props["placeholder"])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/kun/any"
|
||||
"github.com/yaoapp/kun/utils"
|
||||
"github.com/yaoapp/yao/config"
|
||||
_ "github.com/yaoapp/yao/helper"
|
||||
"github.com/yaoapp/yao/model"
|
||||
|
|
@ -68,8 +67,6 @@ func TestProcessData(t *testing.T) {
|
|||
}
|
||||
process := gou.NewProcess("xiang.page.Data", args...)
|
||||
response := ProcessData(process)
|
||||
utils.Dump(response)
|
||||
|
||||
assert.NotNil(t, response)
|
||||
|
||||
res := any.Of(response).Map().Dot()
|
||||
|
|
|
|||
10
tests/langs/zh-hk/pages/lang.yml
Normal file
10
tests/langs/zh-hk/pages/lang.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Start: 開始時間
|
||||
End: 結束時間
|
||||
City: 城市
|
||||
Please select a start time: 請選擇開始時間
|
||||
Please select an end time: 請選擇結束時間
|
||||
Industry: 行業
|
||||
Billing: 計費
|
||||
Merge Reulst: 合併結果
|
||||
Parameter: 參數
|
||||
Merge: 合併
|
||||
100
tests/pages/lang.page.json
Normal file
100
tests/pages/lang.page.json
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"label": "::Demo",
|
||||
"version": "1.0.0",
|
||||
"description": "::Demo",
|
||||
"nodes": [
|
||||
{
|
||||
"name": "行业",
|
||||
"engine": "xiang",
|
||||
"query": {
|
||||
"select": [
|
||||
"city",
|
||||
":COUNT(id) as 数量",
|
||||
"industries[*](string 50) as industry"
|
||||
],
|
||||
"from": "$service",
|
||||
"wheres": [
|
||||
{ "field": "created_at", ">": "?:$from.0" },
|
||||
{ "field": "created_at", "<": "?:$to" }
|
||||
],
|
||||
"orders": "数量 desc",
|
||||
"limit": 100
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "计费",
|
||||
"engine": "xiang",
|
||||
"query": {
|
||||
"select": ["city", ":COUNT(id) as 数量", "price_options[*] as option"],
|
||||
"from": "$service",
|
||||
"wheres": [
|
||||
{ "field": "created_at", ">": "?:$from.0" },
|
||||
{ "field": "created_at", "<": "?:$to" }
|
||||
],
|
||||
"orders": "数量 desc",
|
||||
"limit": 100
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "合并结果",
|
||||
"process": "xiang.helper.ArrayPluck",
|
||||
"args": [
|
||||
["城市", "行业", "计费"],
|
||||
{
|
||||
"行业": { "key": "city", "value": "数量", "items": "{{$res.行业}}" },
|
||||
"计费": { "key": "city", "value": "数量", "items": "{{$res.计费}}" }
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": {
|
||||
"::Merge": "{{$res.合并结果}}",
|
||||
"::Billing": "{{$res.计费}}",
|
||||
"::Industry": "{{$res.行业}}",
|
||||
"::Parameter": "{{$in}}"
|
||||
},
|
||||
"apis": {
|
||||
"data": {
|
||||
"disable": false,
|
||||
"guard": "-",
|
||||
"default": [{ "from": "1980-01-02", "to": "2050-12-31" }]
|
||||
},
|
||||
"setting": { "disable": false, "guard": "-" }
|
||||
},
|
||||
"filters": {
|
||||
"::Start": {
|
||||
"label": "::Start",
|
||||
"bind": "from",
|
||||
"input": {
|
||||
"type": "date",
|
||||
"props": {
|
||||
"placeholder": "::Please select a start time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"::End": {
|
||||
"label": "::End",
|
||||
"bind": "to",
|
||||
"input": {
|
||||
"type": "date",
|
||||
"props": {
|
||||
"placeholder": "::Please select an end time"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"primary": "::City",
|
||||
"layout": {
|
||||
"filters": [
|
||||
{ "name": "::Start", "width": 6 },
|
||||
{ "name": "::End", "width": 6 }
|
||||
],
|
||||
"charts": [
|
||||
{ "type": "line", "props": {} },
|
||||
{ "type": "bar", "props": {} }
|
||||
]
|
||||
},
|
||||
"actions": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
"name": "行业",
|
||||
"engine": "xiang",
|
||||
"query": {
|
||||
"debug": true,
|
||||
"debug": false,
|
||||
"select": [
|
||||
"city",
|
||||
":COUNT(id) as 数量",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue