Unlock SSR Superpowers (Learn and Use Templates In Go)
Tags: go, webdev, beginners, tutorial
Published: 2019-07-31 16:13:54

![](https://cdn-images-1.medium.com/max/800/1*nq-3AgPhq3vj2zewZvFzNA.png)
<figcaption>Photo by John Doyle Unsplash</figcaption>

While developing several full stack apps over years, I realised some apps don’t
need a full fledged frontend application running. Most of these apps serve
static content with dynamic values fitted here and there. For example, consider
your social media feed, each post of a certain type looks same but it gets
populated with data specific to that user. They use some sort of templating to
achieve it.

### What are templates?

Templates are essentially text files that are used to create dynamic content.
For instance the following javascript function takes “name” as argument and
produce different strings.

![](https://cdn-images-1.medium.com/max/800/1*k1QNSXwHwS2ZfUtg_rgseA.png)

We can also use same principal to generate web pages in Go. Web templates allow
us to serve personalised results to users. Generating web templates using string
concatenation is a tedious tasks. It can also lead to injection attacks.

### Templates in go

There two packages in go to work with templates:

1.  [text/templates](https://golang.org/pkg/text/template/) (Used for generating
textual output)
1.  [html/templates](https://golang.org/pkg/html/template/) (Used for generating
HTML output safe against code injection)

Both of them basically have same interface with subtle web specific differences
in latter like encoding script tags to prevent them from running, parsing maps
as json in view.

### Our First Template

{% gist https://gist.github.com/erdahuja/0ac4b4c95db299a1d89974903314be29 %}

<figcaption>Web template in go</figcaption>

1.  The extension of template file could be anything. We are using `.gohtml` so that
it is supported development tools across IDEs.
2.  “Actions” — data evaluations or control structures — is delimited by`{{`and`}}`.
The data evaluated inside it is called *Pipeline*. Anything outside them is send
to output unchanged.

{% gist https://gist.github.com/erdahuja/1c141fab593b5c4a66e88ea72cb5589d.js %}
<figcaption>Code to execute the template with data: Use go run main.go to see output</figcaption>

You can parse multiple files on line:10 as comma separated strings (*path to
file*) or parse all files inside a directory. For example:

    tpl, err := template.ParseFiles(“index1.gohtml”, “index2.gohtml”)
    tpl, err := template.ParseGlob("views/templates/*")

1.  It returns a template container (*here* *called tpl*) and error. We can use our
data to execute *tpl *by calling method Execute*. *In case of multiple
templates, The name of template will be passed as 2nd argument while data being
3rd.
1.  We define our data structure (here type *struct*). It could be anything in go
slice, map, struct, slice-of-structs, structs-of-slice of structs. We will see
each of them shortly.
1.  The data is fetched using *dot (aka cursor). *We use it to access variables of
data inside templates. Remember the identifiers in provided data have to start
with [Capital Case](https://golang.org/doc/effective_go.html#names). We can use
them to initialise a variable inside Actions like`$myCoupon := .Coupon`.
1.  We can output the execution result to web page or standard output because
template Execute method takes any value which implements type Writer interface.

It renders as plain text in output console, but If we use it to send as response
to web request it will be rendered as a web page enabling us to use HTML tags.

![](https://cdn-images-1.medium.com/max/800/1*MOUSBb8bEXN38xcOqrFXng.png)
<figcaption>Standard template output</figcaption>

![](https://thepracticaldev.s3.amazonaws.com/i/rnxseyg3xsa8dee2uycu.png)
<figcaption>Web template output</figcaption>



> *It is preferred to do the parsing job inside init function and execution at
> required places.*

    func init() {
     // Must is a helper that wraps a function returning  
     // (*Template, error) and panics if the error is non-nil.
     tpl = template.Must(template.ParseGlob(“templates/*”))
    }

### Using different data structures in web templates

### Slice (or Array)

Let’s consider a
[slice](https://medium.com/rungo/the-anatomy-of-slices-in-go-6450e3bb2b94) of
strings:
{% gist https://gist.github.com/erdahuja/4f0ce144b359e876b86cf562c81d248b.js %}

<figcaption>Slice of strings in go</figcaption>

This can be used in template by ranging over the Slice (also array) inside
*Actions*. If the value of the pipeline has length zero, nothing will be
executed<br> otherwise, dot(aka *cursor*) is set to the successive elements of
the Slice (also array) and template is executed.

{% gist https://gist.github.com/erdahuja/63066bc2f452786f949de8e1715635a9.js %}

<figcaption>Template for range over slice</figcaption>

![](https://cdn-images-1.medium.com/max/800/1*EFozd10reyZRw2BacjG45A.png)
<figcaption>Web template output</figcaption>

### Map

Let’s consider a [Map](https://blog.golang.org/go-maps-in-action) data
structure:

{% gist https://gist.github.com/erdahuja/aaebdcc36118a072fbec296c1ed3561c.js %}
<figcaption>Map in go</figcaption>

The value of the pipeline inside *Action* is a map. If there are no key values
pairs in map, nothing is output, otherwise, dot (aka *cursor*) is set to the
successive elements of the map and template is executed with `$key` taking each
key, `$val` taking the respective value. If keys are of basic type with a
defined order ("comparable"), the elements will be visited in sorted key order.
{% gist https://gist.github.com/erdahuja/e6ca1cf146434e879f37ba07bf7b529c.js %}
<figcaption>Web template for map</figcaption>

![](https://cdn-images-1.medium.com/max/800/1*jT6bPWb-kWnTC51JZekAxw.png)
<figcaption>Web template output</figcaption>

### Struct

Let’s consider a [struct](https://gobyexample.com/structs) with collection of
fields as declared
[inline](https://stackoverflow.com/questions/26866879/initialize-nested-struct-definition-in-golang):
{% gist https://gist.github.com/erdahuja/a56490c78d6ab07d3dd043a26d56c87f.js %}
<figcaption>Struct in go</figcaption>

The name of a field of the data struct, preceded by a period, such as `.Name` is
the argument in template. The result is the value of the field. Field
invocations may be chained: `.Field1.Field2`. Fields can also be evaluated on
variables, including chaining: `$x.Field1.Field2` . The following template shows
the fields store in variables and then evaluated in *Actions*.

{% gist https://gist.github.com/erdahuja/1e856a1a7086c3d16b7698c9fa0f4951.js %}
<figcaption>Web template for struct in go</figcaption>

![](https://cdn-images-1.medium.com/max/800/1*3faMXA_vAGGpv-2Uxt02XA.png)
<figcaption><br>Web template output</figcaption>

### Slice of structs

Let’s consider a slice of [struct](https://gobyexample.com/structs)s :
{% gist https://gist.github.com/erdahuja/376614730e9074e1f84c581a3f20a1af.js %}
<figcaption>Slice to struct in go</figcaption>

We use range to iterate over slice. The value of the pipeline in Action must be
an array (or slice). If the value of the length of slice is zero, nothing is
output; otherwise, dot (aka *cursor*) is set to the successive elements of the
array, slice and Template is executed.
{% gist https://gist.github.com/erdahuja/adbed8ad28b9bfe2193487df0bfbc625.js %}
<figcaption>Web template for slice of structs</figcaption>

![](https://cdn-images-1.medium.com/max/800/1*5ysnJExJqRAhWUNoZaaF5w.png)

Like this different data structures in go can be combined to make useful
templates.

> A note on Conditionals in templates:

> It is also possible to write conditionals templates `{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}` like this. This gives us amazing abilities to generate dynamic content. If value of pipeline is empty (that is, false, 0, any  nil pointer or interface value, and any array, slice, map, or  string of length zero), T0 is executed else T1 is executed.

### Function In templates

To send a function in go template we can use, by default, no functions are
defined in the template but the `Funcs` method on template can be used to add
function by creating mappings like this:

`template.Must(template.New(“”).Funcs(fm).ParseFiles(“index.gohtml”))`
{% gist https://gist.github.com/erdahuja/9757330fd13e19ae1fe59032ef14d410.js %}
<figcaption>Initialising a function for template in Go</figcaption>

To create a mapping from names to functions we need to use type `FuncMap`. Each
function must have either a single return value, or two return values of which
the second has type error.

    type FuncMap map[]interface{}

On line:7, we have defined a mapping of function *monthDayYear to *name*
fdateMDY. *Now this function can be used inside template. Remember dot (aka
*cursor*) holds the data provided to template.
{% gist https://gist.github.com/erdahuja/26cb0bd8dd3dcbd191c1832b590dd873.js %}
<figcaption>Web template in go using function</figcaption>

These are various ways we can use templates in Go. I will publish how to use
what we learn’t to build our own working web pages using nested templates. You
can drop me hello with questions and feedback on
[twitter](https://twitter.com/Dpkahuja). Please consider leaving a feedback and share with anyone who may benefit from it. Thanks!