mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-09-22 00:20:47 +02:00
This commit is contained in:
parent
e51e6d5662
commit
e4cb124ffd
3 changed files with 85 additions and 69 deletions
|
@ -23,8 +23,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
"text/template/parse"
|
|
||||||
|
|
||||||
"github.com/88250/gulu"
|
"github.com/88250/gulu"
|
||||||
"github.com/88250/lute/ast"
|
"github.com/88250/lute/ast"
|
||||||
|
@ -743,72 +741,6 @@ func (av *AttributeView) Clone() (ret *AttributeView) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (av *AttributeView) GetTemplateKeyRelevantKeys(templateKey *Key) (ret []*Key) {
|
|
||||||
ret = []*Key{}
|
|
||||||
if nil == templateKey || "" == templateKey.Template {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
vars, err := getTemplateVars(templateKey.Template)
|
|
||||||
if nil != err {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, kValues := range av.KeyValues {
|
|
||||||
if gulu.Str.Contains(kValues.Key.Name, vars) {
|
|
||||||
ret = append(ret, kValues.Key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTemplateVars(tplContent string) ([]string, error) {
|
|
||||||
goTpl := template.New("").Delims(".action{", "}")
|
|
||||||
tpl, err := goTpl.Parse(tplContent)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
vars := make(map[string]struct{})
|
|
||||||
collectVars(tpl.Tree.Root, vars)
|
|
||||||
var result []string
|
|
||||||
for v := range vars {
|
|
||||||
result = append(result, v)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func collectVars(node parse.Node, vars map[string]struct{}) {
|
|
||||||
switch n := node.(type) {
|
|
||||||
case *parse.ListNode:
|
|
||||||
for _, child := range n.Nodes {
|
|
||||||
collectVars(child, vars)
|
|
||||||
}
|
|
||||||
case *parse.ActionNode:
|
|
||||||
collectVars(n.Pipe, vars)
|
|
||||||
case *parse.PipeNode:
|
|
||||||
for _, cmd := range n.Cmds {
|
|
||||||
collectVars(cmd, vars)
|
|
||||||
}
|
|
||||||
case *parse.CommandNode:
|
|
||||||
for _, arg := range n.Args {
|
|
||||||
collectVars(arg, vars)
|
|
||||||
}
|
|
||||||
|
|
||||||
if 3 <= len(n.Args) && n.Args[0].Type() == parse.NodeIdentifier && n.Args[1].Type() == parse.NodeDot && n.Args[2].Type() == parse.NodeString {
|
|
||||||
vars[n.Args[2].(*parse.StringNode).Text] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
case *parse.FieldNode:
|
|
||||||
if len(n.Ident) > 0 {
|
|
||||||
vars[n.Ident[0]] = struct{}{}
|
|
||||||
}
|
|
||||||
case *parse.VariableNode:
|
|
||||||
if len(n.Ident) > 0 {
|
|
||||||
vars[n.Ident[0]] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAttributeViewDataPath(avID string) (ret string) {
|
func GetAttributeViewDataPath(avID string) (ret string) {
|
||||||
av := filepath.Join(util.DataDir, "storage", "av")
|
av := filepath.Join(util.DataDir, "storage", "av")
|
||||||
ret = filepath.Join(av, avID+".json")
|
ret = filepath.Join(av, avID+".json")
|
||||||
|
|
|
@ -91,7 +91,7 @@ func getAttrViewAddingBlockDefaultValues(attrView *av.AttributeView, view, group
|
||||||
templateRelevantKeys, rollupRelevantKeys := map[string][]*av.Key{}, map[string]*av.Key{}
|
templateRelevantKeys, rollupRelevantKeys := map[string][]*av.Key{}, map[string]*av.Key{}
|
||||||
for _, keyValues := range attrView.KeyValues {
|
for _, keyValues := range attrView.KeyValues {
|
||||||
if av.KeyTypeTemplate == keyValues.Key.Type {
|
if av.KeyTypeTemplate == keyValues.Key.Type {
|
||||||
if tplRelevantKeys := attrView.GetTemplateKeyRelevantKeys(keyValues.Key); 0 < len(tplRelevantKeys) {
|
if tplRelevantKeys := sql.GetTemplateKeyRelevantKeys(attrView, keyValues.Key); 0 < len(tplRelevantKeys) {
|
||||||
for _, k := range tplRelevantKeys {
|
for _, k := range tplRelevantKeys {
|
||||||
templateRelevantKeys[keyValues.Key.ID] = append(templateRelevantKeys[keyValues.Key.ID], k)
|
templateRelevantKeys[keyValues.Key.ID] = append(templateRelevantKeys[keyValues.Key.ID], k)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,10 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
"text/template/parse"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/88250/gulu"
|
||||||
"github.com/88250/lute/ast"
|
"github.com/88250/lute/ast"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/siyuan-note/logging"
|
"github.com/siyuan-note/logging"
|
||||||
|
@ -746,3 +748,85 @@ func manualSort(view *av.View, collection av.Collection) {
|
||||||
})
|
})
|
||||||
collection.SetItems(items)
|
collection.SetItems(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetTemplateKeyRelevantKeys(attrView *av.AttributeView, templateKey *av.Key) (ret []*av.Key) {
|
||||||
|
ret = []*av.Key{}
|
||||||
|
if nil == templateKey || "" == templateKey.Template {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
vars, err := getTemplateVars(templateKey.Template)
|
||||||
|
if nil != err {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kValues := range attrView.KeyValues {
|
||||||
|
if gulu.Str.Contains(kValues.Key.Name, vars) {
|
||||||
|
ret = append(ret, kValues.Key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if 1 > len(ret) {
|
||||||
|
// 没有相关字段情况下直接尝试解析模板,如果能解析成功则返回模板字段本身 https://github.com/siyuan-note/siyuan/issues/15560#issuecomment-3182691193
|
||||||
|
goTpl := template.New("").Delims(".action{", "}")
|
||||||
|
tplFuncMap := filesys.BuiltInTemplateFuncs()
|
||||||
|
SQLTemplateFuncs(&tplFuncMap)
|
||||||
|
goTpl = goTpl.Funcs(tplFuncMap)
|
||||||
|
_, parseErr := goTpl.Funcs(tplFuncMap).Parse(templateKey.Template)
|
||||||
|
if nil != parseErr {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret = append(ret, templateKey)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTemplateVars(tplContent string) ([]string, error) {
|
||||||
|
goTpl := template.New("").Delims(".action{", "}")
|
||||||
|
tplFuncMap := filesys.BuiltInTemplateFuncs()
|
||||||
|
SQLTemplateFuncs(&tplFuncMap)
|
||||||
|
goTpl = goTpl.Funcs(tplFuncMap)
|
||||||
|
tpl, parseErr := goTpl.Funcs(tplFuncMap).Parse(tplContent)
|
||||||
|
if parseErr != nil {
|
||||||
|
return nil, parseErr
|
||||||
|
}
|
||||||
|
vars := make(map[string]struct{})
|
||||||
|
collectVars(tpl.Tree.Root, vars)
|
||||||
|
var result []string
|
||||||
|
for v := range vars {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectVars(node parse.Node, vars map[string]struct{}) {
|
||||||
|
switch n := node.(type) {
|
||||||
|
case *parse.ListNode:
|
||||||
|
for _, child := range n.Nodes {
|
||||||
|
collectVars(child, vars)
|
||||||
|
}
|
||||||
|
case *parse.ActionNode:
|
||||||
|
collectVars(n.Pipe, vars)
|
||||||
|
case *parse.PipeNode:
|
||||||
|
for _, cmd := range n.Cmds {
|
||||||
|
collectVars(cmd, vars)
|
||||||
|
}
|
||||||
|
case *parse.CommandNode:
|
||||||
|
for _, arg := range n.Args {
|
||||||
|
collectVars(arg, vars)
|
||||||
|
}
|
||||||
|
|
||||||
|
if 3 <= len(n.Args) && n.Args[0].Type() == parse.NodeIdentifier && n.Args[1].Type() == parse.NodeDot && n.Args[2].Type() == parse.NodeString {
|
||||||
|
vars[n.Args[2].(*parse.StringNode).Text] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
case *parse.FieldNode:
|
||||||
|
if len(n.Ident) > 0 {
|
||||||
|
vars[n.Ident[0]] = struct{}{}
|
||||||
|
}
|
||||||
|
case *parse.VariableNode:
|
||||||
|
if len(n.Ident) > 0 {
|
||||||
|
vars[n.Ident[0]] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue