How to render both shortcode and markdown in shortcode?

I know this kind of question has already been asked and answered, but I’m asking again because I couldn’t find answer that works for me.

Before start, markup.goldmark.renderer.unsafe is set to true.

markup:
  goldmark:
    renderer:
      unsafe: true

I have two shortcodes: gallery/image and collapse.

// gallery/image
{{< gallery/image src="063:064" >}}

// collapse
{{% collapse heading="heading text" %}}
{{% /collapse %}}

gallery/image is for displaying multiple images in a row.
collapse is for displaying collapsible content which can be toggled.

I want to use gallery/image inside of collapse like this, with markdown:

{{% collapse heading="heading text" %}}

{{< gallery/image src="063:064" >}}

And this is sample **text**.

{{% /collapse %}}

Some other text are here too.

In collapse.html, it tries to render inner content with this.

{{ .InnerDeindent | htmlUnescape | .Page.RenderString }}

But this simply breaks everything.

Contents of collapse is somewhat partially rendered as code block even though I used .InnerDeindent. Check image below for how it is actually rendered.
It also ‘consumes’ other contents below of it. They are displayed when collapse is expanded instead. For example above, ‘Some other text are here too.’ text are displayed inside of collapse block.

This is totally messed up result. It should display few images and texts.


To achieve my goal, I think it should render shortcode first, then render markdown to get both shortcode and markdown get properly rendered.

But I don’t know how to get raw content of .Inner. .Inner returns template.HTML which is already rendered and useless at this point.

Currently, even though I removed spaces in front of {{ .InnerDeindent | htmlUnescape | .Page.RenderString }}, it still rendered as partial code block.


So… How can I render both shortcode and markdown in shortcode?


PS.
I’ve read a thread introducing a hacky way to render both shortcode and markdown via using code block. I tried to find that thread again for referencing, but I couldn’t find it.
I couldn’t use it because Hugo complains about my shortcode doesn’t use .Inner though…

You may need configure markup.goldmark.renderer.unsafe as true, so that the raw HTML markup blocks won’t be removed.

layouts\shortcodes\collapse.html

{{ .Inner }}

layouts\shortcodes\another-shortcode.html

another shortcode

content/foo.md

title: Foobar

{{% collapse %}}

{{< another-shortcode >}}

And this is sample text.

{{% /collapse %}}

image

The shortcode syntax gives me a headache, I’m not sure if I understand correctly. Take following as example.

{{% foo %}}
{{< bar >}}

ADDITIONAL **MARKDOWN** CONTENT.
{{% foo %}}

The parsing steps:

  1. Parse bar shortcode, assume the content is <strong>bar</strong>.
{{% foo %}}
<strong>bar</strong>

ADDITIONAL **MARKDOWN** CONTENT.
{{% foo %}}

Shortcodes using the % as the outer-most delimiter will be fully rendered when sent to the content renderer.

  1. And then parsing the inner as Markdown, in this step <strong>bar</strong> will be omitted if markup.goldmark.renderer.unsafe wasn’t enable.

Assume that the unsafe is enabled, it may look like.

<strong>bar</strong>

ADDITIONAL <strong>MARKDOWN</strong> CONTENT.
  1. Then you can access the parsed Markdown content (HTML) via .Inner.

I forgot to mention that markup.goldmark.renderer.unsafe is already set to true. I edited my post about it.

Like you said, shortcode using % should render markdown content in it. And since there is another shortcode using < so it will also get rendered. But somehow, shortcode using < isn’t correctly rendered.

I also removed more indentation in my shortcode code, and it partially recovered layout part. I suspect indentation is the problem.


It turned out that another dependency that my shortcode was using has indentation, and it made rendered shortcode become code block.

I copied those dependencies and removed indentation, and now it renders correctly.

Thank you for the help!

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