Escaping HTML in Hugo posts

Or how to indirectly call the safeHTML function

July 6, 2023

Hugo, the static site generation engine (which generates this site) has a useful function called safeHTML which marks an HTML string as “safe”, preventing it from being escaped and displayed literally.

The other day I needed this same behavior but for a variable declared in a post’s frontmatter. “I’ll use that handy safeHTML function” I thought. Wrong! Hugo’s security model doesn’t allow its builtin functions to be called from posts.

Instead Hugo allows posts to embed shortcodes, which are similar to macros. The challenge then, was to concoct a shortcode that would lookup an arbitrary post parameter and mark it as safe.

Here’s what I came up with:

{{ .Get 0 | index $.Page.Params | safeHTML }}

This retrieves the argument from the call stack and looks it up in the post parameters using the index function. This indirection is necessary to enable lookup of arbitrary key names. The lookup result is passed to my old friend, safeHTML.

I saved the shortcode as layouts/shortcodes/safeparam.html.

So imagine you have a fancy HTML table declared in the post frontmatter, you can retrieve it in the post’s content with safeparam:

{{< safeparam "fancy-table" >}}

Tags: hugo html-escape shortcodes