diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 757c1ca7b..8db4ae7e9 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1551,33 +1551,34 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) { } // 再处理模板字段 - - // 渲染模板 + templateKeys, _ := sql.GetTemplateKeysByResolutionOrder(attrView) var renderTemplateErr error - for _, kv := range keyValues { - switch kv.Key.Type { - case av.KeyTypeTemplate: - if 0 < len(kv.Values) { - var ial map[string]string - block := av.GetKeyBlockValue(keyValues) - if nil != block && !block.IsDetached { - ial = sql.GetBlockAttrs(block.BlockID) - } - if nil == ial { - ial = map[string]string{} - } - if nil == kv.Values[0].Template { - kv.Values[0] = av.GetAttributeViewDefaultValue(kv.Values[0].ID, kv.Key.ID, nodeID, kv.Key.Type) - } + for _, templateKey := range templateKeys { + for _, kv := range keyValues { + if kv.Key.ID != templateKey.ID || 1 > len(kv.Values) { + continue + } - var renderErr error - kv.Values[0].Template.Content, renderErr = sql.RenderTemplateField(ial, keyValues, kv.Key.Template) - if nil != renderErr { - renderTemplateErr = fmt.Errorf("database [%s] template field [%s] rendering failed: %s", getAttrViewName(attrView), kv.Key.Name, renderErr) - } + var ial map[string]string + block := av.GetKeyBlockValue(keyValues) + if nil != block && !block.IsDetached { + ial = sql.GetBlockAttrs(block.BlockID) + } + if nil == ial { + ial = map[string]string{} + } + if nil == kv.Values[0].Template { + kv.Values[0] = av.GetAttributeViewDefaultValue(kv.Values[0].ID, kv.Key.ID, nodeID, kv.Key.Type) + } + + var renderErr error + kv.Values[0].Template.Content, renderErr = sql.RenderTemplateField(ial, keyValues, kv.Key.Template) + if nil != renderErr { + renderTemplateErr = fmt.Errorf("database [%s] template field [%s] rendering failed: %s", getAttrViewName(attrView), kv.Key.Name, renderErr) } } } + if nil != renderTemplateErr { util.PushErrMsg(fmt.Sprintf(Conf.Language(44), util.EscapeHTML(renderTemplateErr.Error())), 30000) } diff --git a/kernel/sql/av.go b/kernel/sql/av.go index 7fc8d54bc..8a617a67f 100644 --- a/kernel/sql/av.go +++ b/kernel/sql/av.go @@ -509,7 +509,7 @@ func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection } } -func fillAttributeViewTemplateValues(attrView *av.AttributeView, collection av.Collection, ials map[string]map[string]string, items map[string][]*av.KeyValues, renderedTemplateKeyCollections map[string]av.Collection) (err error) { +func fillAttributeViewTemplateValues(attrView *av.AttributeView, collection av.Collection, ials map[string]map[string]string, items map[string][]*av.KeyValues) (err error) { existTemplateField := false for _, kVals := range attrView.KeyValues { if av.KeyTypeTemplate == kVals.Key.Type { @@ -521,40 +521,34 @@ func fillAttributeViewTemplateValues(attrView *av.AttributeView, collection av.C return } - var renderTemplateErr error - for _, item := range collection.GetItems() { - for _, value := range item.GetValues() { - itemID := item.GetID() - - switch value.Type { - case av.KeyTypeTemplate: // 渲染模板字段 - keyValues := items[itemID] - var ial map[string]string - blockVal := item.GetBlockValue() - if nil != blockVal { - ial = ials[blockVal.Block.ID] - } - if nil == ial { - ial = map[string]string{} - } - content, renderErr := RenderTemplateField(ial, keyValues, value.Template.Content) - value.Template.Content = content - if nil != renderErr { - key, _ := attrView.GetKey(value.KeyID) - keyName := "" - if nil != key { - keyName = key.Name - } - err = fmt.Errorf("database [%s] template field [%s] rendering failed: %s", getAttrViewName(attrView), keyName, renderErr) - } + templateKeys, _ := GetTemplateKeysByResolutionOrder(attrView) + for _, templateKey := range templateKeys { + for _, item := range collection.GetItems() { + value := item.GetValue(templateKey.ID) + keyValues := items[item.GetID()] + var ial map[string]string + blockVal := item.GetBlockValue() + if nil != blockVal { + ial = ials[blockVal.Block.ID] + } + if nil == ial { + ial = map[string]string{} } - if nil != err { - renderTemplateErr = err + content, renderErr := RenderTemplateField(ial, keyValues, value.Template.Content) + if nil != renderErr { + key, _ := attrView.GetKey(value.KeyID) + keyName := "" + if nil != key { + keyName = key.Name + } + err = fmt.Errorf("database [%s] template field [%s] rendering failed: %s", getAttrViewName(attrView), keyName, renderErr) } + + value.Template.Content = content + items[item.GetID()] = append(keyValues, &av.KeyValues{Key: templateKey, Values: []*av.Value{value}}) } } - err = renderTemplateErr return } @@ -765,6 +759,50 @@ func manualSort(view *av.View, collection av.Collection) { collection.SetItems(items) } +func GetTemplateKeysByResolutionOrder(attrView *av.AttributeView) (ret []*av.Key, resolved bool) { + ret = []*av.Key{} + + resolvedTemplateKeys := map[string]bool{} + for i := 0; i < 7; i++ { + templateKeyCount := 0 + for _, keyValues := range attrView.KeyValues { + if av.KeyTypeTemplate != keyValues.Key.Type { + continue + } + + templateKeyCount++ + vars, err := getTemplateVars(keyValues.Key.Template) + if nil != err { + resolvedTemplateKeys[keyValues.Key.ID] = true + ret = append(ret, keyValues.Key) + continue + } + + currentTemplateKeyResolved := true + for _, kValues := range attrView.KeyValues { + if gulu.Str.Contains(kValues.Key.Name, vars) { + if av.KeyTypeTemplate == kValues.Key.Type { + if _, ok := resolvedTemplateKeys[kValues.Key.ID]; !ok { + currentTemplateKeyResolved = false + break + } + } + } + } + if currentTemplateKeyResolved { + resolvedTemplateKeys[keyValues.Key.ID] = true + ret = append(ret, keyValues.Key) + } + } + + resolved = len(resolvedTemplateKeys) == templateKeyCount + if resolved { + break + } + } + return +} + func GetTemplateKeyRelevantKeys(attrView *av.AttributeView, templateKey *av.Key) (ret []*av.Key) { ret = []*av.Key{} if nil == templateKey || "" == templateKey.Template {