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

My [previous blog post](https://alissalozhkin.hashnode.dev/introduction-to-go-templates) 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:

```go
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:

```go
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`.

```go
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:

```go
	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 this is the only string written in the 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.

```go
{{ 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:

```go
-----------------
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:

```go
{{ 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:

```go
-----------------
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:

```go
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:

```go
People: 2
-----------------
Name: Bob
Age: 42
Occupation: Doctor

-----------------
Name: Jessica
Age: 22
Occupation: Unemployed
```
