Go’s html/template escapes ordinary string values according to where they appear in a page. This lets a template display user-supplied text without treating an embedded <script> tag as markup. template.HTML takes a different path: it marks a value as HTML that should be rendered without normal escaping. Use it only when you are responsible for the content being safe to display unescaped. section 9.1.1
A practical use is assembling a page from separately rendered pieces. Render an object with its own template, capture the resulting HTML, then pass it to a page wrapper as template.HTML. The wrapper can insert the fragment without knowing the object’s data type or rendering rules. A reusable rendered fragment can also avoid repeated data lookups and rendering when a page is generated. section 9.1.5
Insert a rendered quote into a page
A quote template supplies the <blockquote> markup and inserts quote fields through template actions. Its rendered output becomes the Content field of a generic page wrapper; declaring that field as template.HTML keeps the blockquote from being escaped when the wrapper renders it. The distinction matters: template.HTML is appropriate for the rendered fragment, not for arbitrary input that happens to contain HTML. section 9.1.5 section 9.1.1
Listing 9.17 Bringing the templates together
package main
import (
"bytes"
"html/template"
"net/http"
)
var t *template.Template #1
var qc template.HTML #1
func init() {
t = template.Must(template.ParseFiles("index.html
", "quote.html")) #2
}
type Page struct { #3
Title string #3
Content template.HTML #3
} #3
type Quote struct { #3
Quote, Name string #3
} #3
func main() {
q := &Quote{ #4
Quote: `You keep using that word. I do not #4
think it means what you think it means.`, #4
Person: "Inigo Montoya", #4
} #4
var b bytes.Buffer #5
t.ExecuteTemplate(&b, "quote.html", q)
qc = template.HTML(b.String()) #6
http.HandleFunc("/", displayPage) #7
http.ListenAndServe(":8080", nil) #7
}
func displayPage(w http.ResponseWriter, r *http.Request) {
p := &Page{ #8
Title: "A User", #8
Content: qc, #8
} #8
t.ExecuteTemplate(w, "index.html", p) #9
}
The Go listing shows the assembly point: a bytes.Buffer receives the object template’s output, and the page’s Content field is typed template.HTML for insertion into the higher-level template. section 9.1.5
