Golang Web App HTML Templating




Welcome to part 16 of the Go Language tutorial series, in this tutorial we will be covering HTML templates with Go. While we can do everything in your .go file, this can become...challenging, especially for larger projects with more complex HTML, styling, as well as the incorporation of JavaScript. With Go, we can use templating and some basic logic from within our HTML files, which will be parsed by Go's html/template package

Besides this tutorial, you should check out the html/template Golang documentation, as we'll just cover some basics and then use it for our needs.

To begin, we'll start with a basic "hello world" example of a golang webapp:

package main

import (
	"fmt"
	"net/http"
)

func indexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<h1>Whoa, Go is neat!</h1>")
}

func main() {
	http.HandleFunc("/", indexHandler)
	http.ListenAndServe(":8000", nil) 
}

So here, we've not used any templating, and we're just returning a simple string of HTML. Now, let's add a new page that utilizes an HTML template.

We'll put this new page under /agg/, since our overarching project is a "news aggregator." So we'll change our main function to:

func main() {
	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/agg/", newsAggHandler)
	http.ListenAndServe(":8000", nil) 
}

Next, we can only pass one object to our template, so we're going to use a struct to be able to pass multiple values. We'll call this struct NewsAggPage, and, for now, we'll just make it fairly arbitrary:

type NewsAggPage struct {
    Title string
    News string
}

Next, before we build our handler, let's not forget to import the html/template

import (
	"fmt"
	"net/http"
	"html/template"
)

Now, let's build our handler, which we'll call newsAggHandler.

func newsAggHandler(w http.ResponseWriter, r *http.Request) {

}

First, we need our page data, which we decided to put into a struct so we could have multiple values. For now, we'll just populate it with something arbitrary:

func newsAggHandler(w http.ResponseWriter, r *http.Request) {
	p := NewsAggPage{Title: "Amazing News Aggregator", News: "some news"}
}

Once we've got the page variables that we want, we also need to bring in the template file:

func newsAggHandler(w http.ResponseWriter, r *http.Request) {
	p := NewsAggPage{Title: "Amazing News Aggregator", News: "some news"}
    t, _ := template.ParseFiles("basictemplating.html")
}

Finally, we can execute the template, with our page variables:

func newsAggHandler(w http.ResponseWriter, r *http.Request) {
	p := NewsAggPage{Title: "Amazing News Aggregator", News: "some news"}
    t, _ := template.ParseFiles("basictemplating.html")
    t.Execute(w, p)
}

Our full Go script now:

//start with web7 / edit7, then we bring in combined2.go.

package main

import (
	"fmt"
	"net/http"
	"html/template"
)

type NewsAggPage struct {
    Title string
    News string
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<h1>Whoa, Go is neat!</h1>")
}

func newsAggHandler(w http.ResponseWriter, r *http.Request) {
	p := NewsAggPage{Title: "Amazing News Aggregator", News: "some news"}
    t, _ := template.ParseFiles("basictemplating.html")
    t.Execute(w, p)
}

func main() {
	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/agg/", newsAggHandler)
	http.ListenAndServe(":8000", nil) 
}

Now, we just need to build our basictemplating.html template file. For this simple case:

<h1>{{.Title}}</h1>
<p>{{.News}}</p>

So you use the double curly braces to notify the template parser that you're intending to pass some sort of value here, and then you can use the dot and the object's name.

We're all set. go run your main webapp file, and visit /agg/ to see your variables live!

Now, of course, what we've done here is something we could have easily done without templates. Let's bring our new skill back to our news aggregator app and see if we can display our findings.

The next tutorial:





  • Introduction to the Go Programming Language
  • Go Language Syntax
  • Go Language Types
  • Pointers in Go Programming
  • Simple Web App in Go Programming
  • Structs in the Go Programming Language
  • Methods in Go Programming
  • Pointer Receivers in Go Programming
  • More Web Dev in Go Language
  • Acessing the Internet in Go
  • Parsing XML with Go Programming
  • Looping in Go Programming
  • Continuing our Go Web application
  • Mapping in Golang
  • Mapping Golang sitemap data
  • Golang Web App HTML Templating
  • Applying templating to our Golang web app
  • Goroutines - Concurrency in Goprogramming
  • Synchronizing Goroutines - Concurrency in Golang
  • Defer - Golang
  • Panic and Recover in Go Programming
  • Go Channels - Concurrency in Go
  • Go Channels buffering, iteration, and synchronization
  • Adding Concurrency to speed up our Golang Web Application