
我想传递一个像“avatars/avatar.png”这样的字符串,但是当我将它传递给模板时,我得到了字符转义。 所以我写了一个传递给模板的函数:
var tpl *template.Template
func init() {
tpl = template.Must(template.ParseGlob("1Forum/static/html/*.html"))
tpl = tpl.Funcs(template.FuncMap{
"unescape": func(s string) string {
unescaped, err := url.PathUnescape(s)
if err != nil {
return s
}
return unescaped
},
})
}
{{unescape .User.Avatar}}
但我仍然收到“未定义函数“unescape””。没有定义 unescape 吗?
“net/url”已导入。
正确答案
unescape 没有定义吗?
技术上来说不是。您确实定义了它,但您这样做为时已晚。函数是否定义是在解析期间检查的,而不是执行期间检查的。您有 parseglob ,然后您执行 tpl.func(...) 。这是不正常的。
而是这样做:
func init() {
tpl = template.Must(template.New("t").Funcs(template.FuncMap{
"unescape": func(s string) string {
unescaped, err := url.PathUnescape(s)
if err != nil {
return s
}
return unescaped
},
}).ParseGlob("1Forum/static/html/*.html"))
}
请注意,转义是一项安全功能,其发生取决于context 您正在使用其中的数据,并且 unescape 可能不会帮助您“欺骗”您的方式,因为转义将会完成在 unescape 的输出上,而不是其输入上。
换句话说,当您执行 {{unescape .}} 时,解析器可能会根据上下文将其转换为 {{unescape . | urlescaper}} (urlescaper 是一个内部转义函数)。为了避免这种情况,当您想要在模板中逐字使用已知的安全字符串时,您应该使用 输入字符串而不是 unescape。
请参阅游乐场示例。
有关上下文、转义、键入字符串等的更多信息,请阅读软件包的文档,一切都解释得很清楚。









