Reputation: 31
I have a wiki web app from the go docs tutorial and want to add a few things. One of those things is a list of all wiki entries at the front page. I have a html template that looks like this:
<h1>This is the front page of the wiki</h1>
<p>here is the list of entries:</p>
<div>
<ul>
{{printf "%s" .Body}}
</ul>
</div>
And here is the handler of the page
func frontHandler(w http.ResponseWriter, r *http.Request){
entries := getEntries()
p := &Page{Title: "FrontPage", Body: []byte(entries)}
renderTemplate(w, "front", p)
}
I've formatted the list of entries to work as a ul in html, it is a splice of strings joined into one to convert it to a splice of bytes, it is formatted like this:
<li><a href="/view/page1">page1</a></li>
<li><a href="/view/page2">page2</a></li>
and so on, so i would like to render it as html instead of plain text like it is now.
I've tried changing how i pass the body of the page from a splice of bytes to a string and it had the same outcome. I tried changing how i render the page to take a different struct made specifically for the front page as a workaround but it also had no effect. Here is how i render the template
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page){
err := templates.ExecuteTemplate(w, tmpl + ".html", p)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
I've also tried a few different ways of showing it in the .html file instead of the {{printf "%s" .Body"}}
and I've been unsuccessful.
Any help is much appreciated, also let me know if i should provide more info.
Upvotes: 0
Views: 2834
Reputation: 41
You can use Typed strings
As per documentation:
By default, this package assumes that all pipelines produce a plain text string. It adds escaping pipeline stages necessary to correctly and safely embed that plain text string in the appropriate context. When a data value is not plain text, you can make sure it is not over-escaped by marking it with its type. Types HTML, JS, URL, and others from content.go can carry safe content that is exempted from escaping.
Example:
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>
<ul>
{{range .}}{{.}}{{end}} <!-- Loop over the pipeline(.) -->
</ul>
</div>
</body>
</html>
func frontHandler(w http.ResponseWriter, r *http.Request) {
entry := []string{"<li><a href=\"/view/page1\">page1</a></li>", "<li><a href=\"/view/page2\">page2</a></li>"}
tmpl, err := template.ParseFiles("base.html")
if err != nil {
log.Fatal("Unable to parse")
}
// template.HTML takes only one string, hence we loop over the entry slice
//and store the slice values in htmlvalues of `HTML` type
var htmlvalues []template.HTML
for _, n := range entry {
htmlEncapsulate := template.HTML(n)
htmlvalues = append(htmlvalues, htmlEncapsulate)
}
tmpl.Execute(w, htmlvalues)
Upvotes: 2