douxing1353 2016-12-20 00:18
浏览 33
已采纳

如何转义模板的输出?

How do I escape an HTML snippet generated by a template? Like in this example:

package main

import (
    "fmt"
    "html/template"
    "os"
)

// I want to escape a html snippet which is then stored as a 
// javascript variable. how can I do that? the second output 
// is the one i would like to generate with a template.

var tmpl = `{{define "main"}}<script>var xx = "{{template "html-snippet" .}}";</script>{{end}}{{define "html-snippet"}}<div>
    <img src="{{.}}">
</div>{{end}}`

func main() {
    t, err := template.New("fo").Parse(tmpl)
    if err != nil {
        fmt.Println(err)
        return
    }
    t.ExecuteTemplate(os.Stdout, "main", "some.jpg")
    fmt.Println("")
    fmt.Println(template.JSEscapeString(`<div>
        <img src="some.jpg">
    </div`))
}

https://play.golang.org/p/TBJxYqokkU

html/template does not do it automatically in my case. JSEscapeString through a func map also does not work (or I don’t know how), because I cannot call it like this {{jsescape (template "html-snippet" .)}}, since this is not a string.

Many thanks

  • 写回答

1条回答 默认 最新

  • dppb79372 2016-12-20 08:51
    关注

    You may register a function which executes the includable template and returns the result as a string. That string can then be inserted into the other template, proper context-sensitive escaping applied automatically:

    var tmpl = `{{define "main"}}<script>var xx = {{exect "html-snippet" .}};</script>{{end}}{{define "html-snippet"}}<div>
        <img src="{{.}}">
    </div>{{end}}`
    
    var t *template.Template
    
    func exect(name string, data interface{}) string {
        buf := &bytes.Buffer{}
        if err := t.ExecuteTemplate(buf, name, data); err != nil {
            fmt.Println("Error:", err)
        }
        return buf.String()
    }
    
    func main() {
        t = template.Must(template.New("fo").Funcs(template.FuncMap{
            "exect": exect,
        }).Parse(tmpl))
        if err := t.ExecuteTemplate(os.Stdout, "main", "some.jpg"); err != nil {
            fmt.Println(err)
        }
    }
    

    Output (try it on the Go Playground):

    <script>var xx = "\u003cdiv\u003e
    \t\u003cimg src=\"some.jpg\"\u003e
    \u003c/div\u003e";</script>
    

    Or even better: the template engine allows you to register functions that return 2 values (second of which must be an error), so our exect() function may look like this:

    func exect(name string, data interface{}) (string, error) {
        buf := &bytes.Buffer{}
        err := t.ExecuteTemplate(buf, name, data)
        return buf.String(), err
    }
    

    Output is the same. Try this one on the Go Playground.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥20 为什么我写出来的绘图程序是这样的,有没有lao哥改一下
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥200 关于#c++#的问题,请各位专家解答!网站的邀请码
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥15 绘制多分类任务的roc曲线时只画出了一类的roc,其它的auc显示为nan
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?