Misunderstanding of shortcode syntax in 0.55

I use shortcodes and since 0.55 I am a bit confused about how it works.

$ hugo version
Hugo Static Site Generator v0.55.3/extended linux/amd64 BuildDate: unknown

My project is using shortcodes in markdown files this way

---
title: A page title
draft: false
---
<div>
{{% intro %}}
# A title with <br /> in
{{% /intro %}}
{{% content %}}
{{% description %}}
## Markdown
{{% /info %}}
{{% practical %}}
## Markdown
{{% /practical %}}
{{% /aside %}}
{{% /content %}}
</div>

Mainly, my shortcodes have this syntax

<div class="wrapper">
  <div class="classname">
    {{ .Inner }}
  </div>
</div>

When I type hugo serve -D only shortcode {{% intro %}} is rendering original markdown and not rendering content in html as others shortcodes are doing.
You can see the results in every page here, at the left of the big red flower https://it-gnosis.eu/

When I read the documentation, I am a little bit confused of what exactly means

outer-most shortcode
fully rendered
old behavior

This solution is working fine

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

But what I am understanding from the documentation is that the inner content is rendered in html. Always in my own understanding, this is the old behavior. I think I miss the point :wink:
I will be happy to help to improve the documentation.

Last thing, I tried a test to understand by creating a test project

When I first launch hugo serve, the markdown was rendered in html. I did a modification in the content file by adding <br /> in the content. The content is rendered with original markdown. I remove the <br/> and my content is still rendered with original markdown.
I also notice that I have the favicon of the previous project which is displayed in the tab.

I agree that the documentation is confusing. The documentation begins with stating, that there are two different types of shortcodes: shortcodes with the % delimiter and shortcodes with the </> delimiters. It then provides two sections:

  • Shortcodes with Markdown
  • Shortcodes without Markdown

In the Shortcodes with Markdown section it mentions the % delimiter and that its behaviour has changed. What follows is also something that I do not get, since I do not know the inner workings of Hugo enough. But in any case: the documentation suggests that, if you want to use markdown within your shortcode, you have to use %, since it definitely will not work with <.

But in Hugo 0.55, markdown does not work within shortcodes at all, at least not without the odd {{ $_hugo_config :={ “version”: 1 }}} setting.

1 Like

If you think you have an idea for improving the documentation, just follow these simple instructions.

Improvement is very welcome and depends upon Community involvement!

First I need to understand what is going on ;). The documentation, as far as I understand it in its current state, states that if you use markdown in your shortcode content, you should use the {{% foo %}} syntax. However this does not work out of the box. Why?

Let’s say you have a markdownify shortcode.

Usecase 1

markdownify.html:

## Heading

{{ .Inner | markdownify }}

The | markdownify part is important now!

{{< markdownify >}}
Paragraph.
{{< /markdownify >}}

Usecase 1 renders your paragraph to HTML—but not the heading in your shortcode file itself.

Usecase 2

markdownify.html:

## Heading

{{ .Inner }}

You do not need markdownify here.

{{% markdownify %}}
Paragraph.
{{% /markdownify %}}

In usecase 2 the heading will be sent to the content renderer—that is it will be rendered to HTML and e.g. part of the TOC.

1 Like

But in both cases the inner content of the shortcode will not be run through the markdown renderer. Is there really no way to do this in 0.55 now? (Without the setting, as already mentioned.)

If using the {{%-syntax it will work as expected as long as you don’t have surrounding html-elements in your shortcode (black friday will not parse markdown inside of html-elements). But because it is usual to have html in the shortcode you have to work around it, see Shortcode - markdown vs html vs table of content for a possible solution.

Also: 0.55 - What am I doing wrong?

You could also use the {{<-syntax and then do {{ .Inner | markdownify }} in your shortcode, as described by @Grob above.

Oh, I see. I did not realize that the surrounding HTML content is the problem.

But that is counter intuitive to the documentation. The documentation lists the {{< syntax clearly under “Shortcodes without markdown” - though i realize now it probably means “Shortcodes without markdown surrounding the inner content” (is that correct?).

I think the documentation needs improvement, but in this case it is correct.

With {{< the inner content will be unparsed and left as is, but you can work around this in your shortcode by adding markdownify.

  • If using {{ .Inner }} in the shortcode the inner content will be left unparsed.
  • If using {{ .Inner | markdownify }} the inner content will parsed and markdown becomes html.

Right. But: what if I want rendered markdown in the inner content of my shortcode and in the content surrounding the inner content of the shortcode? Plus the inner contnet is wrapped by html.

e.g.:

markdownify.html:

## Heading

<div clas="markdownify">
{{ .Inner }}
</div>
{{% markdownify %}}
Paragraph with a [link](https://example.com).
{{% /markdownify %}}

In this case the markdown of the inner content is not rendered to html. Or can I use | markdownify here too?

In this case simply use

## Heading

<div clas="markdownify">
{{ .Inner | markdownify }}
</div>

If you have markdown headings in the .Inner and you want them to show up in a table of contents you can try something like this:

## Heading

 {{ printf "<div clas=\"markdownify\">" | htmlUnescape | safeHTML }}
    {{ .Inner }}
 {{ printf "</div>" | htmlUnescape | safeHTML }}

Thank you @zwbetz for this work around.
See: Shortcode - markdown vs html vs table of content

@Grob but with {{% ? (Sorry, can’t try right now)

Yes, my last suggestion was for the {{%-syntax.

I’m sorry for the confusion. Even if the documentation may not be clear about this, I’m convinced that current behaviour is the correct compromise. The big problem with the pre 0.55 was that it was not possible to have shortcodes that worked with ToC/footnotes – and this will be even more evident pretty soon.

Yes, it was a ‘breaking’ change that caused some confusion, but the advantages are enormous. I am looking forward seeing what happens next.

Just curious to hear: Why was it not possible to generally allow markdown in the shortcodes html files and use {{% and {{< synonymously? And if you like markdown in the content, just use | markdownify. Would it just have been too much of a break?

1 Like

There is a history here. Once we had only {{% and it behave like it does today (more or less). But there where all kinds of issues reported with how the different markdown processors handled inline HTML etc. in Markdwon. So, beyond the very simple examples, if you want to preserve HTML as … HTML without any encoding/formatting issues, you want to use the {{<.

1 Like

I see. Thank you very much for your explanation, @bep.

If this is too much off topic feel free to move my questions to a new topic.


What then is good and future proof shortcode style—particularly for shortcodes you may intend to publish in a theme:

  • Always use {{%—unless you really do not want any markdown rendered to HTML? (As an example the cupper theme uses ‌{{% codePen VpVNKW %}}.)
  • Always use {{< />}}—if required with markdownify—and only use {{% if there is markdown in the shortcode html file itself?
2 Likes

It’s hard to make a general rule, but the above isn’t one I would live by. The thing is that for this:

{{% myshortcode %}}

## A Markdown header

{{< someothershortcode >}}

{{% /myshortcode %}}

It is the total output that is sent as part of the surrounding document to the Markdown processor, not just the “shortcode itself”.

In the above it is obvious that you want to use “{{%”, for the codePen I would guess (I have not looked at it) that “{{<” would be a more sensible choice.

2 Likes