Learning to Go: Part 2 - HTML Templates

The Golang gopher

Oh hi! This is a multi-part tutorial series, please make sure you reads the posts in order:
Part 0 - Part 1 - Part 2 - Part 3 - Part 4 - Part 5 - Part 6

Welcome back fellow Go newbies! In this stage of our tutorial we’ll use a templating library to help us render more stylish HTML, without having to embed a bunch of HTML and CSS directly into our Go code.

As this is not an HTML or CSS tutorial, I’ve written these files for you. First copy the index.html file into the same directory as your main.go file:

Next, create a sub-directory called assets and put the following style.css file in there:

Now we need to make some updates to our main.go file. First we need to add an extra import for the html/template library. Since we now have multiple imports, we can group them together inside brackets. Replace your previous import statement with this:

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

Then under the imports, add this new line:

var tpl = template.Must(template.ParseFiles("index.html"))

Here we’re defining a global variable called tpl which uses the template library’s ParseFiles function to load our index.html. It wraps this in the Must function which just means that our program will exit if for any reason it can’t load this file.

Inside of our indexHandler function, removing line containing the “Hello World” statement and replace it with:

tpl.Execute(w, nil)

Here we’re running the Execute function on our tpl variable, and sending it the http.ResponseWriter that’s assigned to the variable w. In plain english, this causes the template to be rendered, and the output sent to the HTTP response.

We can try running our updated program now, just like before:

go run main.go

If we load http://localhost:8080 in a browser we can see our new index.html file, but it doesn’t look quite right. Our index.html file refers to /assets/style.css, but that’s not loading because our program forwards all requests to our indexHandler.

Rather than create a new handler for our CSS file, we’ll create a static file server that can serve anything out of our /assets directory by default. We do this by adding the following lines inside the main function, just after we create the mux variable:

fs := http.FileServer(http.Dir("assets"))
mux.Handle("/assets/", http.StripPrefix("/assets/", fs))

Here we’re creating a variable called fs which is a FileServer from the http library. Then we add it as a handler to our mux variable. So now any requests that start with /assets will be dealt with by the static file server, rather than needing their own handler and function.

If your Go program is still running, use Control+C to quit out of it, then run it again once you’ve saved your changes.

You should now see an updated index page, complete with CSS styling!

TNG search

Nice work! We’re now using multiple libraries, and our app can serve different paths with different functions. Now move on to part 3.

Here’s the complete code of main.go if you need to check yours for errors:

Share this on:
comments powered by Disqus