{{< html-shortcodes >}} are rendered as markdown when nested inside {{% markdown-shortcodes %}}. Is there a workaround?

TL;DR: how can I prevent {{< html-shortcodes >}} nested inside of {{% markdown-shortcodes %}} from being treated as markdown (with <p> tags added)?

Things I’ve already read

These two links looked very relevant, but did not contain actual solutions to the problem:

Apparently, the second issue was closed since “there is a simple workaround or solution to this.” I looked at the issue/PR referenced in regard to this behavior (https://github.com/gohugoio/hugo/issues/797 – limited to only 2 links by Discourse since I’m a new user…), and it seems to me like nested shortcodes being rendered as markdown is by intentional design. So I’m quite curious to hear what the workaround is, as I believe it is my exact problem.

And this one looked kinda-sorta relevant, but I think it is different:

  • https://github.com/gohugoio/hugo/issues/1642

Longer description

I have a wrapper shortcode in my project for expanding and collapsing content:

<div class="content-section">
{{ .Inner }}
</div>

I can use JavaScript to show/hide these sections independently, if the user decides they want to read more about something. Simple enough. This shortcode is called with the shortcode syntax that renders the inner content as mardkown:

{{ % toggleable-content %}}

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

{{ % /toggleable-content %}}

I have a second shortcode used to display a list of section-level links to a subject index (the following is simplified, but is the gist):

<div style="display: flex; flex-wrap: wrap;">
{{ .Inner }}
</div>

This shortcode uses the syntax that renders the inner content directly as HTML. It is called like so:

{{< subject-links >}}
<a href="/subject-index/#subject-1">This is is the very long link text of subject 1</a>
<a href="/subject-index/#subject-2">This is is the very long link text of subject 2</a>
<a href="/subject-index/#subject-3">This is is the very long link text of subject 3</a>
{{< /subject-links >}}

This second shortcode works fine when when not nested inside a {{% markdown-shortcode %}}, but when it is, a <p> tag is added, messing things up. That is, when it is called like this:

{{ % toggleable-content %}}
{{< subject-links >}}
<a href="/subject-index/#subject-1">This is is the very long link text of subject 1</a>
<a href="/subject-index/#subject-2">This is is the very long link text of subject 2</a>
<a href="/subject-index/#subject-3">This is is the very long link text of subject 3</a>
{{< /subject-links >}}
{{ % /toggleable-content %}}

It leads to this:

<div  style="display: flex; flex-wrap: wrap;">
<p>
<a href="/subject-index/#subject-1">This is is the very long link text of subject 1</a>
<a href="/subject-index/#subject-2">This is is the very long link text of subject 2</a>
<a href="/subject-index/#subject-3">This is is the very long link text of subject 3</a>
</p>
</div>

The text in the links now improperly wraps, as it is now treated as inline within the <p> tag.


Just for some context, here’s the visual difference between when things are rendered properly (top) vs. when the inner shortcode is rendered as markdown and a <p> tag is added (bottom)

Well…

Of course right after going to the trouble of writing everything up, it occurred to me that perhaps it is a newline-related thing with how the markdown renderer generally or Goldmark specifically handles the HTML being fed into it.

I’ve previously had issues with indented things in my shortcodes getting treated as code blocks (the markdown renderer treats things with multiple leading spaces as code blocks). So all of my {{< html-shortcodes >}} used inside of {{% markdown-shortcodes %}} lack indentation, which makes them difficult to maintain code-wise, but at least they render properly.

So too here, it seems. I literally just refactored my shortcode from

<div style="display: flex; flex-wrap: wrap;">
{{ .Inner }}
</div>

To

<div style="display: flex; flex-wrap: wrap;">{{ .Inner }}</div>

(No new lines), and it appears to be working properly now.


Still happy to hear from anyone more experienced if there is a cleaner and/or more elegant way to deal with these things. This is not the first time I’ve been bit by strange interactions between HTML shortcodes and the markdown renderer. Perhaps it is just somewhat the nature of the beast and there’s not much to be done, but I for one would appreciate it if things were a little more clear and intuitive, as I always kind of feel like I’m guessing and praying when trying to get things to render properly.

2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.