When you’re building a website, you’ll typically generate some of your final content dynamically. You’ll then want to inject that data into your final web pages for display in a browser.

You can take one of two approaches: embed your page structure into your program, or combine your final data with separate template files.

Templating provides separation of concerns for a more maintainable codebase. It also makes it easier to split front-end tasks and back-end tasks, allocating them to different team members. Go has excellent templating support in its standard library.

Getting Started With Templating in Go

Go has two templating packages in the standard library: text/template and html/template. The text/template package has functionality for parsing text files, while html/template handles HTML. By using the html/template you’re secured from cross-site scripting (XSS) attacks since Go escapes data entry during rendering. This is another advantage of templating over a manual approach.

Since the template package is part of the standard library, you won’t need to install any dependencies; just import it:

        import "html/template"

Start by creating an HTML file to use as a template for your application. You can use the standard .html extension or either .gohtml or .tmpl, both are which are also common. Whatever extension you use, the functionality within your application will be the same. Some text editors may apply different syntax highlighting depending on your templates’ extensions. Here’s a basic skeleton:

        <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
 
</body>
</html>

Save this file in your Go program’s directory. You can now start to work with it, as a template, within your program.

Create a global instance of the Template method of the template package. You’ll access this template instance from various parts of your program.

        var tmplt *template.Template

You’ll have to create a simple server to render and display your templates. Here’s how to start a simple server in Go using the net/http package:

        func runServer() {
    http.HandleFunc("/home", handlePage)
    err := http.ListenAndServe("localhost:8080", nil)
 
    if err != nil {
        log.Fatalln("There's an error with the server:", err)
    }
}

You’ll call the runServer function from your main function to start the server. The server has only one route, the /home route, which will display your page. The handlePage parameter is the name of a handler function that will render your page. The ListenAndServe method starts the server listening on port 8080 on localhost, i.e. your own computer.

Passing Variables to Templates

Create a global struct named News:

        type News struct {
    Headline string
    Body string
}

You’ll use this struct to store data and pass it to your template for display on your final page. In your template, you can then use this syntax to inject data:

        {{ name }}
    

Where name is the name of a variable you have passed to your template. When you render the template, it will replace values in braces with corresponding data from your Go code. Since the following example will pass a struct, you’ll use dot notation to access its fields:

        <body>
    <h1>{{ .Headline }}</h1>
    <p> {{ .Body }} </p>
</body>

Replace the empty body element in your template’s skeleton markup with the code above.

The handlePage handler function will verify that the request for the page is a GET request. It then populates a struct with sample data before rendering the template and serving the final page:

        func handlePage(writer http.ResponseWriter, request *http.Request) {
    if request.Method == "GET" {
        tmplt, _ = template.ParseFiles("tutorial.html")
 
        event := News{
            Headline: "makeuseof.com has everything Tech",
            Body: "Visit MUO for anything technology related",
        }
 
        err := tmplt.Execute(writer, event)
 
        if err != nil {
            return
        }
    }
}

The ParseFiles method parses the HTML file you specify. The event variable is the initialized struct. The Execute method will inject the supplied data into the final page, according to the placeholders in the template. Execute takes a ResponseWriter and the data, in this case, the struct.

Here’s the result from running the server and visiting the page:

A web page with a heading and a paragraph of text

Using Control Structures in Templates

You can also use control structures like conditional statements, and loops in your templates.

A loop allows you to output several values and reuse the same structure for each. Use the range keyword to define the beginning of the repeated content and the end keyword for the end. Within the loop you can use the {{.}} syntax to inject the current value:

        <ol>
    {{range .}}
    <li>{{.}}</li>
    {{end}}
</ol>

Then you’ll pass the name of the data structure you want to loop through as a parameter to the Execute method:

        makeUseOfCategories := []string{"Technology Explained", "Programming", "Linux",
   "Android", "iOS", "Many More................"}
 
err := tmplt.Execute(writer, makeUseOfCategories)
 
if err != nil {
    return
}

The makeUseOfCategories variable is a slice of strings to pass as the data parameter. Here’s the result of looping through the slice:

A web page showing a list of MUO categories

You can use a conditional statement in your templates to test the value of a boolean variable. Create a struct with boolean fields, like this:

        type TrueFalser struct {
    IsTrue bool
    IsFalse bool
    IsDefault bool
}

To use a conditional, include the if keyword in double braces before the name of the variable to test. End the conditional block with the end keyword in braces:

        {{if .IsTrue}}
    <p>Evaluates true and will output</p>
{{end}}
 
{{if .IsDefault}}
    <p>Evaluates false and won't output</p>
{{end}}
 
{{if .IsFalse}}
    <p>Evaluates false and won't output</p>
{{end}}

Initializing a struct in Go sets the values to false on default, so if you do not initialize a field, it evaluates to false. On initializing the struct and passing the variable as the data to the template, only the fields that evaluate to true cause output to appear.

        choice := TrueFalser {
    IsTrue: true,
    IsFalse: false,
}
 
err := tmplt.Execute(writer, choice)

The final output includes just a single paragraph since only the isTrue field evaluates to true:

A web page showing a single occurrence of the phrase 'evaluates true'.

You Don’t Have to Use Templates for Your Backend Applications

Templating isn’t a requirement for your Go apps. You can use other approaches like embedding your page structure into your program, alongside its logic and other behavior.

However, you’ll end up making more work for yourself. Go templating helps prevent XSS attacks and makes it easier to separate work on page structure from backend logic.