Kazu's Log

Jun 18, 2016

How to use if in Go's html/template

Hugo uses Go’s html/template which has its own langugage that is different from Go’s own syntax.

What I wrote today, for showing both English and Japanese posts, but only show the content of the Japanese posts on each post’s individual page is,

{{ if or (ne .Params.lang "japanese") (.Scratch.Get "IsSingle") }}
<div class="content">{{ .Content }}</div>
{{ else }}
<div class="content"></div>
{{ end }}

That was hard to figure out. Let me explain each syntax element.

if

That is straightforward.

{{ if condition }}
Show this section if the condition is true
{{ else }}
Show this section if the condition is false
{{ end }}

or and ne

html/template shares the syntax with text/template and the syntax is mostly explained in the latter’s one.

The documentation here focuses on the security features of the package. For information about how to program the templates themselves, see the documentation for text/template.

text/template doesn’t provide operators, but it provides functions such as and, or, not, eq or ne.

The syntax for calling functions is

function arg1 arg2... argN

Commas are not needed, parenthesis are optional for calling functions, but needed for nesting invocations. That results the below which reminds me Lisp.

{{ if or (ne .Params.lang "japanese") (.Scratch.Get "IsSingle") }}

partial and .Scratch

The last ones are for Hugo, not Go.

partial is a function which takes 2 parameters - the file location and the variables to be passed down to the file.

In my case, layouts/index.html has

{{ range $paginator.Pages }}
  {{ .Scratch.Set "IsSingle" false }}
  {{ partial "article.html" . }}
{{ end }}

layouts/_default/single.html has

{{ .Scratch.Set "IsSingle" true }}
{{ partial "article.html" . }}

The . on partial means “pass all variables in this scope to the partial”. However it prevents access to variables Hugo has. Then article.html doesn’t have a way to say “if this partial is render in X”.

Hugo has Scratch which is useful to workaround the issue.

I used that for adding additional parameters to the argument of partial. Actually this technique was explained in How to identify single pages in Hugo and I just copied that.

Mini Language Woes

I’m not a big fan of “mini” languages. I prefer eRuby on Ruby, and EJS on JavaScript because it reduces the cognitive load of switching multiple languages.

No offence. Unlike Ruby and JavaScript, Go is a compiled language and there is no eval. So the decision to make a mini language is totally reasonable.