Golang authors have an excellent article on how to build a wiki web application entirely out of go. Towards the middle of the article, they mention the html/template package. For those of you familiar with templating systems like jade, handlebars, or flask/jinja… you should feel right at home. In golang, templating needs no third party frameworks, no extensions… it comes right out the box.
But, I did have a big “D’Oh” moment when using this engine for the first time. While looking up how to include conditional (if…else) and iterative (for loop) structures in the template I ran into a brick wall and simply couldn’t find the syntax. I automatically assumed all the documentation for the package was under the URL:
http://golang.org/pkg/html/template/
No mention of the syntax for the structures I needed. I quite by accident then ran across the text/template package and documentation here:
http://golang.org/pkg/text/template/
The first paragraph mentions:
To generate HTML output, see package html/template, which has the same interface as this package but automatically secures HTML output against certain attacks.
So I tried out the control structures there and it worked perfectly… As an example (using bootstrap for CSS), say we would like to display a bunch of alerts whose content is retrieved from a golang array:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Start Webserver Section | |
*/ | |
type Page struct { | |
Title string | |
Body string | |
Alerts []string | |
} | |
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) | |
} | |
} |
in the above, we note the “Alerts” string array contained within a “Page” struct, and just as explained in the golang article, we have a function to render templates that accept a variable p which is a pointer to the struct.
Within the html file that is rendered by the html/template package, we have the following:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> | |
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> | |
</head> | |
<body> | |
<div class="container well"> | |
<h2>Alerts</h2> | |
<hr> | |
{{range $element := .Alerts}} | |
<div class="alert alert-danger">{{$element}}</div> | |
{{end}} | |
</div> | |
</body> | |
</html> |
Note lines 10-12. Golang uses the familiar double curly brackets to enclose it’s syntax within a template. In this example, we used the “range” syntax to assign each element of the array Alerts to the variable $element, which is in turn used within the div.
Make sure to checkout http://golang.org/pkg/text/template/ for more examples of the logic that you can place within templates