英文:
Escaping "/" in template
问题
我想传递一个像这样的字符串"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}}
但是我仍然得到"function 'unescape' not defined"的错误。难道unescape
没有被定义吗?
"net/url"已经被导入。
英文:
i wanto to pass a string like this "avatars/avatar.png" but when i pass it to the template i get the character escaped.
So i wrote a func that i pass into template:
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}}
But i continue to get "function "unescape" not defined". Isn't unescape defined?
"net/url" is imported.
答案1
得分: 2
"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"))
}
请注意,转义是一种安全特性,它取决于你在何种上下文中使用数据,而unescape
可能无法帮助你绕过转义,因为转义将在unescape
的输出上进行,而不是它的输入。
换句话说,当你使用{{unescape .}}
时,解析器可能会根据上下文将其转换为{{unescape . | urlescaper}}
(urlescaper
是一个内部转义函数)。为了避免这种情况,当你有一个已知安全的字符串要在模板中直接使用时,应该使用类型化字符串,而不是unescape
。
请参考playground示例。
有关上下文、转义、类型化字符串等更多信息,请阅读该包的文档,其中清楚地解释了这些内容。
英文:
> Isn't unescape defined?
Technically not. You do define it, but you do so too late. Whether a function is defined or not is checked during parsing, not execution. You have ParseGlob
and then you do tpl.Func(...)
. That's out of order.
Instead do:
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"))
}
Note that the escaping, which is a security feature, happens depending on what context you are using the data in, and unescape
is likely not going to help you "cheat" your way around that because the escaping will be done on the output of unescape
, rather than its input.
In other words, when you do {{unescape .}}
, the parser may, depending on the context, turn that into {{unescape . | urlescaper}}
(the urlescaper
is an internal escaping function). To avoid this, when you have a known secure string that you want to use verbatim in the template, you should use a typed string instead of unescape
.
See playground example.
For more info on the contexts, escaping, typed strings, etc. read the package's doc, it's all there clearly explained.
答案2
得分: -1
“function 'unescape' not defined”错误消息表示您定义的自定义函数在模板上下文中不可访问。要使该函数在模板中可用,您需要在定义模板时将其作为值传递给Funcs方法:
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
},
})
确保在渲染模板时将tpl值传递给Execute方法:
err := tpl.Execute(w, data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
这样应该使得unescape函数在您的模板中可用,并且您应该能够在不遇到“function 'unescape' not defined”错误的情况下使用它。
希望对您有所帮助。
英文:
The error message "function "unescape" not defined" indicates that the custom function you defined is not accessible in the template context. To make the function available to your template, you need to pass it as a value to the Funcs method when defining your template:
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
},
})
Make sure to pass the tpl value to the Execute method when rendering the template:
err := tpl.Execute(w, data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
This should make the unescape function available in your templates and you should be able to use it without encountering the "function "unescape" not defined" error.
I hope this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论