Using custom variables for HTML tags

I’m looking for a concise way of putting different HTML tags in a template, based on the page it’s rendered on.

{{ $tag := cond .IsHome "h1" "h2" }}
<{{ $tag }}><a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a></{{ $tag }}>

The above conditional works, but the output of $tag is escaped, including the preceding < tags, turning it into:

&lt;h2><a href="...">...</a>&lt;/h2>

Is there a better, clean way to do it? Or a way to prevent Go template from escaping the <s?

Have you tried using safeHTML?

Untested, but try piping your tag(s) to safeHTML or htmlEscape

Neither {{ $tag | htmlEscape }} nor {{ $tag | safeHTML }} make any difference :frowning:

What about {{ printf "<%s>" $tag | safeHTML }} ?

1 Like

No, still not there. <{{ printf "%s" $tag | safeHTML }}> also outputs &lt;h2>, and putting the whole tag inside printf, ie. {{ printf "<%s class="...">" $tag | safeHTML }} causes errors. Plus, readability suffers and it’s quite wordy :frowning:

As a test, the following works fine for me locally. You likely got an error because you didn’t escape the quotes

{{ $tag := "h1" }}
{{ printf "<%s class=\"some-class\">Hello World</%s>" $tag $tag | safeHTML }}

Update: Probably irrelevant, but just learned you can pass a single arg to printf then use it multiple time with [1]

{{ printf "<%[1]s class=\"some-class\">Hello World</%[1]s>" $tag | safeHTML }}
4 Likes

The second version is interesting, thanks, though still not very readable :pensive: Guess that’s a limitation of Go templates that cannot be easily overcome.

Would you rather “readable” or “working” :slight_smile: ?

Out of the options that work, I usually choose the one that’s most readable, even at the cost of some efficiency or code duplication. My current best option, considering these priorities, is:

{{ if .IsHome }}
<h1>...</h1>
{{ else }}
<h2>....</h2>
{{ end }}

I was just hoping for something shorter.