Gotya: Go Templates
2020-08-02 — 5 mins reading time
Since I started to use Hugo for creating this web site, I more or less willingly came into contact with Go Templates. I then thought, that this could be a good solution for generating LaTeX invoices: simply use placeholders in a tex file and replace them with actual values using Go Templates. Thus, as my first Go project, I decided to build a simple tool first: It shall take variables from a YAML input file and then generate a text file based on a template referencing these variables.
The code/files I mention in this article are also available on Github. If you don’t want to copy/paste everything, you can simply checkout the repository.
The target picture
Let’s define a simple set of variables in a YAML file (values.yaml
):
|
|
Thus, I want to be able to use strings as well as numbers and I shall also be able to create complex objects and arrays (which becomes important when you have a long list of variables for each item on your invoice).
As test template, let’s use the following one (template.txt
):
|
|
This is the standard feature set of Go Templates, with the addition of the function add
which adds two numbers. Interestingly, Go Templates does not offer arithmetics in the template itself. Anyway, it will show that the template language can be easily extended.
The actual Go program
This won’t be a Go tutorial, so you might want to read up a few things first. And since the code is more or less straight forward, I simply paste it here in it’s entirety (save it as main.go
):
|
|
Before you can compile it, you still need to install the YAML package:
|
|
After that, you can build and run it:
|
|
Why gotya
? Well, “Go Template tool, Yet Another one” ;-)
The output:
|
|
Some interesting things
|
|
Go is a typed language, and normally, we would define a struct with all the variables and provide this to the template.Execute
function. However, we do not know the YAML file’s content beforehand, so we declare an interface as a map type.
|
|
We can extend the template language by custom functions. This is certainly just a simple example, but basically you can define whatever complex function you need.
And now with LaTeX
The beauty of the above program: You can use it with whatever text file you like. Almost.
LaTeX actually makes heavy use curly braces, and as you can see above, the Go template languages does the same in its standard configuration. Luckily, the delimiters of the template language can be changed. Simply provide them during instantiation of the template object:
|
|
The actual invoice in LaTeX
This will be part of a later article, so stay tuned.
Alternatives
The initial problem could be actually solved in many different ways. There are many other text templating tools around and in production use.
One of them for the Go template language is gomplate, also written in Go. This is the above example on steroids. It already has loads of integrated custom functions as well as support for many more data sources, including environment variables (important in the world of Docker), JSON and YAML. Thus, you might want to consider using this one instead of writing one of your own.
Another one is j2cli which is based on Jinja and supports also the use of environment variables. The syntax of Jinja is different, so it is more a matter of what kind of syntax you are already used to. Plus, you need python as a dependency to use j2cli.
Go programs, by nature, are statically linked and thus standalone. Which not always is an advantage since it results in larger-than-usual executable files. gomplate, for instance has a file size of about 35 MB (v3.7.0), our above example code already results in about 4 MB – we are talking about command line tools here without any fancy UI.