32

I have written a shortcode to create a bootstrap dismissable alert box. Below is my shortcode called as layouts/shortcodes/message.html.

   <div class="alert alert-{{.Get 0}} alert-dismissible fade show" role="alert">
       {{.Inner}}
     <button type="button" class="close" data-dismiss="alert" aria-label="Close">
       <span aria-hidden="true">&times;</span>
     </button>
   </div>

This is how I am calling from my content markdown file:

{{% message warning%}}
This can cause build errors
{{% /message %}}

However, in the output HTML, below code is generated :

<!-- raw HTML omitted -->
<p>This can cause build errors</p>
<!-- raw HTML omitted -->

I don't understand what's wrong here. I have created other shortcodes (not using .Inner though, this is my first attempt) and they work fine e.g. I created a shortcode for a image grid like pinterest that accepts upto 10 image URLs and spits out HTML. Not sure why this specific .Inner shortcode fails. Please help. My Hugo version is v0.74.3/extended darwin/amd64.

EDIT

When I use the tags {{< >}} instead of {{% %}} then it works. But I may put some markdown in Inner Text and hence would like to use {{% %}}.

If I understand correctly, using {{% %}} will first process the markdown inside the Inner Text and then will pass that to the shortcode as .Inner.

Naveen
  • 7,944
  • 12
  • 78
  • 165

2 Answers2

54

This is the most frequently asked question in Newest 'hugo' Questions - Stack Overflow within the last 5 days!¹

In your Hugo config file, you need to tell the default Markdown renderer, which is Goldmark, to render raw HTML. If you use a config.yaml, use this:

markup:
  goldmark:
    renderer:
      unsafe: true

If you use a config.toml, use this:

[markup]
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true

I wrote about this on my website in http://www.ii.com/hugo-tips-fragments/#_markup.

SomeShinyObject
  • 7,581
  • 6
  • 39
  • 59
n m
  • 1,601
  • 6
  • 8
  • Where is the html? If I understand correctly, the job of Markdown renderer is done before the control goes to markdown code. In other words, `{{.Inner}}` should have the processed output from Goldmark, before shortcode adds the wrapper html. – Naveen Aug 03 '20 at 10:04
  • If you use `{{% message warning %}}` and `{{% /message %}}`, everything that is returned by the shortcode is passed through to the markup renderer, which in your case is Goldmark. Your returned content includes `
    – n m Aug 03 '20 at 15:50
  • I just tested this with Markdown[^] and I think you will get the behavior you were expecting if you put `{{ $_hugo_config := \`{ "version": 1 }\` }}` at the top of your shortcode code. The behavior of `{{%` changed in Hugo v0.55.0 and there is lots of discussion about this, for example in [Shortcode - markdown vs html vs table of content - support - HUGO](https://discourse.gohugo.io/t/shortcode-markdown-vs-html-vs-table-of-content/18282) (includes info relevant to you) [^] I mainly use Asciidoc, which includes explicit syntax to "pass through" HTML (`+`, `+++`, `++++`, and the `pass:` macro – n m Aug 03 '20 at 17:01
  • 2
    Could this solution be posted to the hugo documentation at https://gohugo.io/templates/shortcode-templates/? I'm sure this is being asked a lot because it is something that everyone always wants to do. Even the tutorial video on that page demonstrates this error. (An even better solution would be to change this anti-feature. Why would you want your shortcode to fail because you used {{< >}} instead of {{% %}}?) – Kenneth Moreland Aug 06 '21 at 03:17
  • 1
    Thanks for explaining this. It was just what I was looking for. – oscarmlage Nov 21 '21 at 20:24
  • Great - thanks! For some reason my Hugo site only recently developed this issue. Added your code to netlify.toml and it's fixed. Thanks! – Sherrie Gossett Dec 08 '22 at 05:29
1

If you would like to keep your markdown render safe (e.g. if you have guest authors on your site or want to prevent blog post writers from adding javascript to their posts) then you can use the markdownify function in your shortcode as follows:

   <div class="alert alert-{{.Get 0}} alert-dismissible fade show" role="alert">
       {{ .Inner | markdownify }}
     <button type="button" class="close" data-dismiss="alert" aria-label="Close">
       <span aria-hidden="true">&times;</span>
     </button>
   </div>

Then in your content markdown file:

{{< message warning >}}
This can cause build errors
{{< message />}}

This seemed to be the best and simplest solution for us because it did not require us to modify our global configuration.

bbengfort
  • 5,254
  • 4
  • 44
  • 57