How to Create Plaintext Reports in Go Using Templates with Loops and Conditionals

My previous blog post introduced templates in Go by demoing how to produce a simple string using the template.New().Parse
function. In this blog post, I will go over the steps on how to use the text/template
package with loops and conditional logic to produce a plaintext report. This demo will be using the template.New().ParseFiles
function.
First off, we introduce a feature of templates called actions
. An action
, defined as {{ <action> }}
, may be a for-loop, conditional statement, or even a custom function defined by the user. Using the same starter code as in the last post, we have:
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
Age int
Employed bool
Occupation string
}
func main() {
// insert code here
}
Note that whenever we want to export a variable or a function in Go, the variable name must begin with a capital letter. Hence, the Person
struct and all of its attributes begin with capital letters.
The next step is to create a template file which we will call demo.tmpl
. For now, this file will contain some basic text:
Nothing here yet
In main.go
, we create a slice containing a couple of Person
objects, which we will then pass to the template file by calling template.Execute
.
func main() {
people := []Person{
{
Name: "Bob",
Age: 42,
Employed: true,
Occupation: "Doctor",
},
{
Name: "Jessica",
Age: 22,
Employed: false,
Occupation: "",
},
}
}
In the same file, we then call template.New().ParseFiles
. This function initializes a template with the filename demo.tmpl
and parses it to ensure that there are no syntax errors. The panic
function ensures quick error-handling. We then execute the template using template.Execute
, with the slice people
as the second argument, as can be seen below:
tmplFile := "demo.tmpl"
tmpl, err := template.New(tmplFile).ParseFiles(tmplFile)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, people)
if err != nil {
panic(err)
}
If we run go run main.go
, on the terminal will be printed the string nothing here yet
, as there is nothing else in the template file at the moment.
We therefore begin populating the template file. We can use the range
action to iterate through the slice that was passed in.
{{ range . }}
-----------------
Name: {{.Name}}
Age: {{.Age}}
{{ end }}
In the command {{ range . }}
, the .
represents the slice. The range
action is also terminated with {{ end }}
. In the code block above, we access the name and age of each Person
object in the people
slice. Running go run main.go
gives us the following result:
-----------------
Name: Bob
Age: 42
-----------------
Name: Jessica
Age: 22
We want to display the occupation of each Person
conditionally: if Employed
is true, then display the occupation, otherwise display Unemployed
. Both the if
and else
actions are used for this as seen below:
{{ range . }}
-----------------
Name: {{.Name}}
Age: {{.Age}}
Occupation: {{ if .Employed }}{{ .Occupation }}{{ else }}Unemployed{{end}}
{{ end }}
Note that the conditional statement is also terminated with {{ end }}
. Running go run main.go
gives us the following result:
-----------------
Name: Bob
Age: 42
Occupation: Doctor
-----------------
Name: Jessica
Age: 22
Occupation: Unemployed
At the top of the file, we want to include the number of people contained in the slice. We can do so by using the len
action like so:
People: {{ len . -}}
{{ range . }}
-----------------
Name: {{.Name}}
Age: {{.Age}}
Occupation: {{ if .Employed }}{{ .Occupation }}{{ else }}Unemployed{{end}}
{{ end }}
Note that in the command {{ len . -}}
, the .
represents the slice and the -
indicates that a newline character \n
should not be printed after the first line. Running go run main.go
gives us the final result:
People: 2
-----------------
Name: Bob
Age: 42
Occupation: Doctor
-----------------
Name: Jessica
Age: 22
Occupation: Unemployed
Subscribe to my newsletter
Read articles from Alissa Lozhkin directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Alissa Lozhkin
Alissa Lozhkin
My name is Alissa and I am a fourth-year computer science and math student at the University of Toronto! I am very interested in computer science and software development, and I love learning about new technologies! Get in touch with me on LinkedIn: https://www.linkedin.com/in/alissa-lozhkin