/home/josephspurrier

How to Use Template Blocks in Go 1.6

In Go 1.6, there will be a new action in the template package called block. The block is designed to act just like template, but has a default value which can be overwritten using define actions whereas template does not have a default value and requires define actions. For this demonstration, there are two web pages: a Home page and an About page. I’ll explain how the template action works and how you can change your templates to use the new block action. There are also two types of templates used in this demonstration: base and content. The base template contains the structure of the page while the content templates hold the actual content.

Note: You can now natively embed assets in Go 1.16.

Content Templates

Each of the content templates corresponds to a page.

Home Template (home.tmpl)

{{define "title"}}Home{{end}}
{{define "content"}}This is the Home page.{{end}}

About Template (about.tmpl)

{{define "title"}}About{{end}}
{{define "content"}}This is the About page.{{end}}

Base Template

This is the base template (base.tmpl):

<title>{{template "title" .}}</title>
<body>{{template "content" .}}</body>

Code to Render

In this example, notice how the base template (base.tmpl) is listed as the first argument to ParseFiles() and the content template is listed second. If you reverse the order, nothing will display so order is important.

This is the code to render the Home page:

t, err := template.ParseFiles("base.tmpl", "home.tmpl")
if err != nil {
	log.Fatal(err)
}

if err := t.Execute(os.Stdout, nil); err != nil {
	log.Fatal(err)
}

This is how the Home page will render:

<title>Home</title>
<body>This is the home page</body>

This is the code to render the About page:

t, err := template.ParseFiles("base.tmpl", "about.tmpl")
if err != nil {
	log.Fatal(err)
}

if err := t.Execute(os.Stdout, nil); err != nil {
	log.Fatal(err)
}

This is how the About page will render:

<title>About</title>
<body>This is the about page.</body>

Limits of Template Action

Imagine if the website had 500 content templates. In order to add a footer section to base.tmpl that pulls content from the content templates, you have to go through all 500 of those content templates and add a define action or else you would get an error like this:

no such template "footer"

Edit on 1/24/2016: saturn_vk on reddit pointed out that you can add define actions to the bottom of the base template to get rid of the errors.

The New Block

Now let’s convert the template actions to block actions. You don’t have to change any code in your content templates, you just have to update your base template (base.tmpl) to look like this:

<title>{{block "title" .}}Default Title{{end}}</title>
<body>{{block "content" .}}This is the default body.{{end}}</body>

The default content will show if your content templates don’t have a matching define. Now you can build in inheritance to your templates and the code won’t throw any errors if something is missing from a content template.

#go #code