Chapter 16 - HTML Templates
Exercise 1: A Text Template
We want to create a text template that will output a bulleted list (using simple dash characters as the bullets).
Set the templateText
variable so that the program will produce the output shown. Don’t forget that you need a
newline character to make the output skip to the next line!
package main
import (
"log"
"os"
"text/template"
)
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
func executeTemplate(templateText string, data interface{}) {
tmpl, err := template.New("template").Parse(templateText)
check(err)
err = tmpl.Execute(os.Stdout, data)
check(err)
}
func main() {
// YOUR CODE HERE:
// Set templateText so that the calls to executeTemplate
// below will produce the output shown.
templateText := ""
executeTemplate(templateText,
[]string{"apples", "oranges", "pears"})
executeTemplate(templateText,
[]string{"chicken", "beef", "lamb"})
}
Output:
- apples
- oranges
- pears
- chicken
- beef
- lamb
When you’re ready, have a look at our solution.
Exercise 2: An HTML Template
Copy the code below to grocery.go
and list.html
files, both saved in the same directory. Then fill in the missing code in both files.
When a browser visits http://localhost:8080/fruit
, your app should respond with this HTML (the spacing doesn’t have to match):
<html>
<ul>
<li>apples</li>
<li>oranges</li>
<li>pears</li>
</ul>
</html>
And when a browser visits http://localhost:8080/meat
, your app should respond with this HTML:
<html>
<ul>
<li>chicken</li>
<li>beef</li>
<li>lamb</li>
</ul>
</html>
Try running your finished app, and visit the above URLs in your browser!
grocery.go
package main
import (
"html/template"
"log"
"net/http"
)
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
func writeList(writer http.ResponseWriter, list []string) {
// YOUR CODE HERE: Use the template library to parse the contents
// of the "list.html" file. You'll get a template value and an
// error value.
// Pass the error value to the "check" function.
// Now call the "Execute" method on the template. It should write
// its output to the "writer" parameter, and it should use the
// "list" parameter as its data value.
// You'll get another error value back from "Execute", which
// should be passed to "check".
}
func fruitHandler(writer http.ResponseWriter, request *http.Request) {
writeList(writer, []string{"apples", "oranges", "pears"})
}
func meatHandler(writer http.ResponseWriter, request *http.Request) {
writeList(writer, []string{"chicken", "beef", "lamb"})
}
func main() {
http.HandleFunc("/fruit", fruitHandler)
http.HandleFunc("/meat", meatHandler)
err := http.ListenAndServe("localhost:8080", nil)
log.Fatal(err)
}
list.html
<html>
<ul>
<!-- YOUR CODE HERE:
The data value passed to the template should be a slice.
Loop over each element in the slice, and include them in
the output, enclosed in <li></li> tags. -->
</ul>
</html>
Here’s our solution.