Shortcode - markdown vs html vs table of content

With 0.55.0 the behavior of “{{%”-shortcode changed so that markdown-headings in a shortcode ends up in the table of content.

This is great, but unfortunately it’s no longer possible to add styles via html in the shortcode to be applied to the inner markdown content of the shortcode.

I’m aware of why this is the case (blackfriday) and the solutions to get the old behavior either by adding:

{{ $_hugo_config := `{ "version": 1 }` }}

at the top of the shortcode or by modifying the shortcode with:

{{ .Inner | markdownify }}

but what I want is to be able to style markdown content with html in the shortcode AND render occuring markdown headers in the table of content.

  • Is this or will this ever be possible?
  • What is the use case that introduces this change in behavior?
1 Like

Can you give an example of what you mean by this? As in what worked before (style wise) but no longer works

What I’m looking for is to both be able to add style in the shortcode and render markdown headers in the table of contents. This has never worked but from where I stand it seems to be the desired behavior.

In the example below the style in the shortcode will be applied to .Inner, but .Inner will not be markdownified because Blackfriday will not process markdown inside of html elements.


Page markdown

# Heading1

Some text...

{{% myshort %}}
## Heading2

Some text...

## Heading3

More text...
{{% /myshort %}}

myshort shortcode

<div class="style1 style2">
      {{- .Inner -}}

Desired result

The style will be applied to the markdownified .Inner and the toc will look like this:

  • Heading 1
    • Heading 2
    • Heading 3

I see your issue now, and I can reproduce this on my end. After a bit of tinkering, here is a workaround for you.

In your myshort.html shortcode do

{{ printf "<div class=\"style1 style2\">%s</div>" .Inner }}

Then in your template where you render your content do

{{ .Content | htmlUnescape | safeHTML }}

Yes, that works! Very cool! Thanks! :slight_smile: (But is it a hack or actually a good solution that should be in the docs? :slight_smile: For one thing I’ve seen @bep advise against using “{{%” due to unpredictable behavior of the blackfriday markdown renderer…)

Trying to avoid changing the template I came up with this (a nested div and three printf:s to avoid a oneliner):

 {{ printf "<div class=\"style1\">" | htmlUnescape | safeHTML }}
 {{ printf "<div class=\"style2 style3 \">%s</div>" .Inner | htmlUnescape | safeHTML }}
 {{ printf "</div>" | htmlUnescape | safeHTML }}

And it works!

It’s crucial to have 1-3 space before the first {{. zero or four spaces won’t work. But I’m not sure why!


I don’t think it’s intended behavior. I’d recommend creating an issue at Issues · gohugoio/hugo · GitHub with a detailed test case and then linking this thread