HTML in nested shortcode gets escaped

My site uses shortcodes for info boxes, e.g.


<div class="note">
<div class="info-header"> Note</div>
<div class="info-body">{{ .Inner | markdownify }}</div>

This works fine with Markdown and even inline HTML. It does however fail with shortcodes who generate HTML themselves:

{{< note >}}

<a href="#">Works</a>
{{< doc "Fails" >}}   # becomes <pre><code>escaped HTML</code></pre>

{{< /note >}}

I also looked into .RenderString but it doesn’t appear to offer anything different in this department. And falling back onto Blackfriday has no future.

Is there any way I can work around this limitation? I employ class attributes as in the above shortcode, so I cannot easily switch to pure Markdown for the nested shortcodes.

I don’t know a technical work around, but as this comes up often, my suggestion is to make shortcode pairs for shortcodes used for adding structure tags.

Personally I’d just write the HTML, but if you want to add HTML tags without adding HTML to content files, then make an opening shortcode, and an ending shortcode. Then they just add the opening and closing HTML elements.

What happens if you close your doc shortcode? like {{<doc "fails" / >}} or with a {{< /doc >}}

@maiki You mean like:


<div class="note">
  <div class="info-header"> Note</div>
  <div class="info-body">



And then using it like:

{{< note-open >}}
…regular markdown here…
{{< note-close >}}


That works, and thanks for the idea, but that seems like a really unfortunate hack. Even dynamically rewriting the DOM via Javascript seems more appealing.

Adding raw HTML each time is out of the question – I’m writing documentation (almost 200 pages by now) and the files need to stay clean. If it was just a small website or blog, where posts are “finished” products unlikely to be revised a lot, then I might feel different about it.

Somehow I didn’t expect this to be a genuine limitation. I mean, certainly nesting can be expected to be common for all but the simplest of pages. I wanted to treat shortcodes like “macros” in programming languages, but if Hugo demands that everything stay in Markdown (I already had to enable unsafe = true in Goldmark) then that takes away a lot of the appeal, since Markdown and HTML have limited overlap.


Aren’t {{< tag >}} {{< /tag }} pairs only for shortcodes that contain and process something in between?

The {{< doc "name" >}} tag is a single tag (with an optional second argument) and some adaptive processing behind it. I don’t think I can turn it into a tag pair. {{< doc "name" / >}} throws a Hugo error.