What am I even on about

Golang Templates

Another major feature Golang offers are templates. I’m not talking HTML specifically, just about anything that’s made up of text can be turned into a template and generated with Golang, think config files, emails, csv, etc..
Although I will be covering HTML templates in the near future, I won’t be in this post. As the parser exposed by html/template has a twist that should be covered thoroughly.

Using templates in Golang is fairly simple once you grok the basics, it might seem a bit odd at first, but there’s a big advantage to splitting up the templating in a couple of steps.

  • Create a template object
  • Parse the template into the template object
  • ‘Execute’ the template, which will fill the parsed template
  • Grab the output!

Let’s generate a vCard, this format is normally used to export contact details for use on various email clients (you can directly import these on iOS and Android too simply by opening them).

which results in,

In the execute step you bind the instance of a single struct to the template, you can access properties of said struct like so: {{.SomeProperty}}, the dot indicates you’re grabbing something from the bound model. Remember you can only bind a single model to the template, so the bound struct should contain all the data you want inserted into the template.

A big advantage of splitting up the parsing and filling/outputting the template is that we can reuse the template without having to parse it again, which is a major performance improvement (hence why hugo has such insane compile speeds on big sets of posts compared to alternatives).

So now the principles and advantages of this approach become clear, let’s check out some control structures too. Let’s make our generator a bit more advanced by adding conditional blocks. It’s worth mentioning that Golang’s templating system actually utilizes a different parser than the Go compiler itself. You can’t just drop Go code into your templates.
Let’s checkout how to add an if statement to check if certain fields on our structs have been filled. One important thing to note is that the comparisons within a template are still typed. So, when checking for the existence of a string, we need to compare it to its initial value, which is just an empty string.

The if conditional requires a bool, so we make sure the statements proceeding it evaluate to a boolean. ne stands for ‘not equals’ or ‘!=’. Long story short, the Phonenumber line will not be rendered into the result if none is filled in, but will if the phonenumber IS set. A full list of operators can be found here.

Ranges can also be used and iterated over within a template, let’s check that out by generating a CSV spreadsheet file of employee’s over at our mock company.

Which results in

Thanks for reading!

Leave a Reply