Go Template Engine

By: Stephen Patrick | 11 Sep 2016 | Category: Go Template Engine

Go Template Engine

Go provides a template engine that allows us to define a template consisting of text that conforms to some desired structure with data to produce a final output. We can parameterize a template with meaningful argument names. At runtime the data passed to the template is matched with the arguments by the template engine and the argument placeholders are expanded to produce output for a given context.

There are many templates engines in existence. Some Web frameworks provide there own template engine or allow it to be customized with an existing or custom template engine. Normally template engines fall into a number of categories. Some template engines may compile the templates, and others may interpret the template at runtime. Normally a template engine enforces some constraints on how we work with templates. Some template engines enforce us to use a declarative syntax, or logic-less templates while others allows us to use embedded logic, by using programming constructs directly in a template such as sequence, selection, and iteration constructs, as well as variable declaration and assignment statements. Normally a template engine exists somewhere between logic-less and embedded logic templates.

Go HTML Templates

Go templates are text documents. The Go templates exist in the package text/template for generating textual content and html/template for generating html content. Let’s look at a simple example.

<!DOCTYPE html>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Go HTML Templates</title>
</head>
<body>
 {{ . }}
</body>
</html>

As mentioned go templates consist of text content. We place the above template into a file called helloword.html. We use the syntax (.) above to tell the Go template engine to perform an action. The . between the braces is an action and it tells the Go template engine to replace it with a value at runtime.

Go Template Rendering

Lets look at a simple example to render a template with Go. To render a Go template we must first parse the template and then call the Execute function.

package templates

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

func renderHelloWorldTemplate(w http.ResponseWriter, r *http.Request) {
   t, err := template.ParseFiles("./resources/helloworld.html")
   if err !=nil {
       panic(err)
   }
   t.Execute(w, "Hello World!")
}

Above we create a new function called renderHelloWorldTemplate. This function takes a ResponseWriter and a Request object. The response writer is used to output the result of rendering the template to the response. To render the template we must first parse the template by calling template.ParseFiles. If an error is returned we simply panic and end execution. If the template is parsed we call the Execute function, passing the response writer and the content used to replace the action (.) that we defined.

Let’s take a look at the code that was used to craft and drive the above code. This code is contained in the file called introduction_test.go.

package templates

import (
"testing"

"net/http"
"net/http/httptest"
"strings"
)

func TestHelloWorldTemplate(t *testing.T) {
   expected := `<!DOCTYPE html>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Go HTML Templates</title>
</head>
<body>
 Hello World!
</body>
</html>`
   req, _ := http.NewRequest("GET", "/templates/hello", nil)
   res := httptest.NewRecorder()
   renderHelloWorldTemplate(res, req)
   responseBody := string(res.Body.Bytes()[:])
   if strings.TrimSpace(responseBody) != strings.TrimSpace(expected) {
       t.Errorf("Expected output did not match Expected: %s but Got: %s",expected, responseBody)
   }
}

Above we create a new function called: TestHelloWorldTemplate. We also use the net/http/httptest package to create a mock http response and a request object to pass to the function renderHelloWorldTemplate. We then compare the body of the mock response object to our expected output.

Executing the template would write the following output to the response.

<!DOCTYPE html>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Go HTML Templates</title>
</head>
<body>
 Hello World!
</body>
</html>

The code for this examples can be found here.