在范围内转义模板

escape template in range

我想像这样打印用户列表:<@user1> <@user2>,这是我公司内部的内部格式,但 golang 模板总是将 < 转义为 &lt;。我的代码:

tpl, _ := template.New("text").Parse(`{{range .Users}} <@{{.}}> {{end}}`)
var buffer bytes.Buffer
tpl.Execute(&buffer, struct {
    Users []string
}{
    Users: []string{"user1", "user2"},
})
fmt.Println(buffer.String())

预计:

<@user1> <@user2>

输出:

 &lt;@user1>  &lt;@user2> 

如何解决这个问题?

如果您想这样做,请使用 text/template。这是文档的一部分,以便更好地理解每个文档:

Godoc: html/template:

此包封装了包 text/template,因此您可以共享其模板 API 以安全地解析和执行 HTML 模板。

tmpl, err := template.New("name").Parse(...)
// Error checking elided
err = tmpl.Execute(out, data)

如果成功,tmpl 现在将是注入安全的。否则,err 是文档中为 ErrorCode 定义的错误。

HTML 模板将数据值视为应进行编码的纯文本,以便它们可以安全地嵌入到 HTML 文档中。转义是上下文相关的,因此操作可以出现在 JavaScript、CSS 和 URI 上下文中。

此包使用的安全模型假定模板作者是可信的,而执行的数据参数不是。下面提供了更多详细信息。

例子

import "text/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")

产生

Hello, <script>alert('you have been pwned')</script>!

但是 html/template

中的上下文自动转义
import "html/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")

产生安全的、转义的HTML输出

Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!