🎨 Improve HTML content rendering for database template fields https://github.com/siyuan-note/siyuan/issues/16362

Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
Daniel 2025-11-17 10:14:48 +08:00
parent d15f957239
commit 8cfae95f29
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
2 changed files with 32 additions and 2 deletions

View file

@ -111,7 +111,7 @@ func renderView(attrView *av.AttributeView, view *av.View, query string, depth *
return return
} }
func RenderTemplateField(ial map[string]string, keyValues []*av.KeyValues, tplContent string) (ret string, err error) { func renderTemplateField(ial map[string]string, keyValues []*av.KeyValues, tplContent string) (ret string, err error) {
if "" == ial["id"] { if "" == ial["id"] {
block := getBlockValue(keyValues) block := getBlockValue(keyValues)
if nil != block { if nil != block {
@ -267,6 +267,11 @@ func RenderTemplateField(ial map[string]string, keyValues []*av.KeyValues, tplCo
ret = buf.String() ret = buf.String()
if ret == "<no value>" { if ret == "<no value>" {
ret = "" ret = ""
return
}
if util.HasUnclosedHtmlTag(ret) {
ret = util.EscapeHTML(ret)
} }
return return
} }
@ -623,7 +628,7 @@ func fillAttributeViewTemplateValues(attrView *av.AttributeView, view *av.View,
ial = map[string]string{} ial = map[string]string{}
} }
content, renderErr := RenderTemplateField(ial, keyValues, value.Template.Content) content, renderErr := renderTemplateField(ial, keyValues, value.Template.Content)
if nil != renderErr { if nil != renderErr {
key, _ := attrView.GetKey(value.KeyID) key, _ := attrView.GetKey(value.KeyID)
keyName := "" keyName := ""

View file

@ -100,6 +100,31 @@ func UnescapeHTML(s string) (ret string) {
return return
} }
func HasUnclosedHtmlTag(htmlStr string) bool {
tagRe := regexp.MustCompile(`<(/?)([a-zA-Z0-9]+)[^>]*?>`)
selfClosing := map[string]bool{
"br": true, "img": true, "hr": true, "input": true, "meta": true, "link": true,
}
stack := []string{}
matches := tagRe.FindAllStringSubmatch(htmlStr, -1)
for _, m := range matches {
isClose := m[1] == "/"
tag := strings.ToLower(m[2])
if selfClosing[tag] {
continue
}
if !isClose {
stack = append(stack, tag)
} else {
if len(stack) == 0 || stack[len(stack)-1] != tag {
return true // 闭合标签不匹配
}
stack = stack[:len(stack)-1]
}
}
return len(stack) != 0
}
func Reverse(s string) string { func Reverse(s string) string {
runes := []rune(s) runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {