HTML templates
suggest changePackage html/template
has the same base functionality as text/template
.
The difference is that html/template
understands structure of HTML and JavaScript code inside HTML.
Inserted text is escaped based on its surrounding context which eliminates cross-site scripting bugs.
const tmplStr = `<div onlick="{{ .JS }}">{{ .HTML }}</div>
`
txt := text_template.Must(text_template.New("text").Parse(tmplStr))
html := html_template.Must(html_template.New("html").Parse(tmplStr))
data := struct {
JS string
HTML string
URL string
}{
JS: `foo`,
HTML: `<span>text</span>`,
URL: `http://www.programming-books.io`,
}
err := txt.Execute(os.Stdout, data)
if err != nil {
log.Fatalf("t.Execute() failed with '%s'\n", err)
}
fmt.Println()
err = html.Execute(os.Stdout, data)
if err != nil {
log.Fatalf("t.Execute() failed with '%s'\n", err)
}
<div onlick="foo"><span>text</span></div>
<div onlick=""foo""><span>text</span></div>
Inserting unescaped HTML
Sometimes you need to subvert escaping of text:
const tmplStr = `<div onlick="{{ .JS }}">{{ .HTML }}</div>
`
html := template.Must(template.New("html").Parse(tmplStr))
data := struct {
JS string
HTML string
}{
JS: `foo`,
HTML: `<span>text</span>`,
}
fmt.Printf("Escaped:\n")
err := html.Execute(os.Stdout, data)
if err != nil {
log.Fatalf("t.Execute() failed with '%s'\n", err)
}
fmt.Printf("\nUnescaped:\n")
data2 := struct {
JS template.JS
HTML template.HTML
}{
JS: `foo`,
HTML: `<span>text</span>`,
}
err = html.Execute(os.Stdout, data2)
if err != nil {
log.Fatalf("t.Execute() failed with '%s'\n", err)
}
Escaped:
<div onlick=""foo""><span>text</span></div>
Unescaped:
<div onlick="foo"><span>text</span></div>
template.HTML
and template.JS
are type alises for string
so you can assign string values to them.
Templating engine recognizes those types and disables escaping for them.
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents