Google go templates

Tue Aug 10 11:25:35 CEST 2010

Until now, the homepage used HTML embedded in source code, rendered the content (which is in markdown format), concatenated the strings and printed that stuff to stdout.

Today I exported this code into templates. The main layout of the page as well as the layout of the blog are now contained in templates. The template files can be found here.

The template engine I use is the template package of Go.

The template package provides almost no control flow. A template is executed on some data, which may be a map m or some type t. Then a string of the form {field} is replaced by the contents of m[field] or t.field or t.field() respectively.

For deeper nested data structures, the template package provides a notion of a “current position” or a “cursor”, denoted by @. To go deeper into a data structure, {.section field} ... {.end} is used. The cursor then is set to m[field] or t.field etc. Any further substitution is then used on whatever m[field] is.

If we for example have the following map

m := map[string]string{
  "foo": map[string]string{
    "bar": "baz"}}

and the template string

{.section foo}

then this is substituted by m["foo"]["bar"], i.e. by baz.

Finally, if you want to iterate over some data structure, then this is supported by {.repeated section field} ... {.end}, where m[field] is required to be some array or slice. The cursor is set to the element in question and the sub code is executed.

The template package also provides some other features, of which I will mention just one: filter. Some field can be passed through a filter, and the result is substituted. This is denoted by {field|filter}. There is, for example, the html filter provided by the template package. This filter html-escapes the contents of the field before substituting it.

A filter I implemented is the md filter, which pipes the content of the field through a markdown processor and inserts the result as a string.

This is used in the main template. This template is called with three fields:

  • title: The title of the page
  • menu: The rendered menu
  • content: The content to be rendered

The content is not substituted as is, though, but is first passed through the markdown processor. This is achieved via {content|md}.

Copyright © 2010 Christian von Essen < christian at mvonessen dot de >