Skip to main content

Command Palette

Search for a command to run...

Templates: Introduction to HTML Templates

Updated
2 min read

There are many scenarios in which we want to create templates suitable for web applications. It is possible to write HTML templates dynamically using the text/template package, however using html/template makes your HTML templates injection-safe as it automatically escapes HTML characters that are found in the input. For example, if the input contains characters such as <, >, or &, the html/template package will convert these characters to &lt;, &gt;, and &amp; respectively so that they don’t interfere with the overall HTML structure. In most cases, the input for templates come from unknown sources, and so html/template should be used to produce HTML templates.

We begin with the same code in main.go as in my previous blog post:

package main

import (
    "html/template"
    "os"
    "strings"
)

type Person struct {
    Name       string
    Age        int
    Employed   bool
    Occupation string
    Interests  []string
}

func sub(i int) int {
    return i - 1
}

func main() {
    people := []Person{
        {
            Name:       "Bob",
            Age:        42,
            Employed:   true,
            Occupation: "Doctor",
            Interests:  []string{"Reading", "Swimming"},
        },
        {
            Name:       "Jessica",
            Age:        22,
            Employed:   false,
            Occupation: "",
            Interests:  []string{"Piano", "Baking"},
        },
        {
            Name:       "Ben",
            Age:        23,
            Employed:   false,
            Occupation: "",
            Interests:  []string{"Music", "Running"},
        },
    }
    tmplFile := "demo_html.tmpl"
    fMap := template.FuncMap{
        "sub":  sub,
        "join": strings.Join,
    }
    tmpl, err := template.New(tmplFile).Funcs(fMap).ParseFiles(tmplFile)
    if err != nil {
        panic(err)
    }
    file, err := os.Create("layout.html")
    if err != nil {
        panic(err)
    }
    err = tmpl.Execute(file, people)
    if err != nil {
        panic(err)
    }
}

Note that I created a new template file demo_html.tmpl. Also, instead of outputting the template to the terminal, I chose to write it to a file called layout.html.

In demo_html.tmpl, we write the following code:

{{ range . }}

<h1> Name: {{.Name}} </h1>
<ul>
<li> Age: {{.Age}} </li>
<li> Occupation: {{ if .Employed }}{{ .Occupation }}{{ else }}Unemployed{{end}} </li>
<li> Interests: {{ join .Interests " & " }} </li>
</ul>

{{ end }}

After saving this file and running go run main.go, opening layout.html reveals the following:

<h1> Name: Bob </h1>
<ul>
<li> Age: 42 </li>
<li> Occupation: Doctor </li>
<li> Interests: Reading &amp; Swimming </li>
</ul>


<h1> Name: Jessica </h1>
<ul>
<li> Age: 22 </li>
<li> Occupation: Unemployed </li>
<li> Interests: Piano &amp; Baking </li>
</ul>


<h1> Name: Ben </h1>
<ul>
<li> Age: 23 </li>
<li> Occupation: Unemployed </li>
<li> Interests: Music &amp; Running </li>
</ul>

You can see in layout.html that the & characters are escaped by html/template package. Running layout.html will give the following on a web browser: