在模板中转义”/”字符的方法是使用双斜杠”//”。

huangapple go评论88阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年2月11日 09:43:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75417610.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定