How to unmarshal JSON containing shortcode

We have the following:

{{< card >}}
title: Heading and body
body:
  Content of the third card.
  {{< badge primary >}}Sample badge{{< /badge >}}
{{< /card >}}

We unmarshal this in the card shortcode, using transform.Unmarshal. That fails, stating:

error calling Unmarshal: “_stream.yaml:17:1”: failed to unmarshal YAML: yaml: line 17: could not find expected ‘:’

Are we incorrect in expecting that JSON string to come back unprocessed? Even if the shortcode is evaluated first (which it shouldn’t be), the result is valid YAML. So any idea what might be going wrong?

What is the badge shortcode?

Something like this will fail:

<div class="{{ .Get 0 }}">
  {{ .Inner }}
</div>

…because the closing div starts a column 0, not column 2 (the joys of YAML indentation). You would need to do something like this instead:

<div class="{{ .Get 0 }}">
  {{ .Inner }}
  </div>

You don’t need to indent the first line because it is already indented in the parent.

As soon as lose the indentation, you terminate the block, so the line is a key, and you don’t have a : value after it, hence the error.

https://yaml-multiline.info/

Oh, wow, that is unexpected. The shortcode indeed generated something like <span>...</span>, but probably with a few leading and trailing newlines.

To work around that issue, the best I have for now is an inline shortcode that indents content acceptably:

{{ $body := trim .Inner "\n" }}
{{- $m := findRE "^[ ]*" $body -}}
{{- $indent := len (index $m 0) -}}
{{- $prefix := strings.Repeat $indent " " -}}
{{- range (split $body "\n") -}}
{{ $prefix }}{{ . | safeHTML }}
{{ end }}

To be used as:

{{< card >}}
title: Heading and body
body:
  Content of the third card.

  {{< inline >}}
    {{< badge primary >}}Sample badge{{< /badge >}}
  {{< /inline >}}
{{< /card >}}

That looks really fragile to me. I’m not sure what you’re doing, and I really don’t want to know, but you might step back for a minute or two… maybe there’s a more solid way of doing what you want.

More robust may be to switch to an indent-less format like TOML. (Tested and that works without jumping through any hoops.)