Shortcode supporting both closing and non-closing mode

Hello folks,

I’d like to implement a shortcode which supports getting its working content either from .Inner, or a file= parameter pointing to a javascript file to load.

My shortcode works fine with the code below, but what I have noticed is, as soon as I mention .Inner in the shortcode – even in a branch which is never executed – the page content terminates immediately after the first calling of the shortcode.

Here’s my example:

{{- $width := cond .IsNamedParams (.Get "width") (.Get 0) | default "100%" -}}
{{- $height := cond .IsNamedParams (.Get "height") (.Get 1) | default "30rem" -}}
{{- $chart_filename := (.Get "file") -}}
{{- $scratch := newScratch -}}
{{- $scratch.Set "absolute_filename" "" -}}
{{- with .Get "file" -}}
    {{- $chart_name := index (split (path.Base $chart_filename) ".") 0 -}}
    {{- $chart_absolute_filename := add "/" $chart_filename -}}
    {{- $scratch.Set "absolute_filename" $chart_absolute_filename -}}
    {{- $id := add "echart_" $chart_name -}}
    {{- $scratch.Set "divid" $id -}}
{{- else -}}
    {{- $content := .Inner | transform.Unmarshal | jsonify -}}
    {{- $id := dict "Content" $content "Scratch" .Page.Scratch | partial "function/id.html" -}}
    {{- $scratch.Set "divid" $id -}}
    {{ errorf "Provide either 'file=' parameter, or content of chart to display." }}
{{- end -}}
{{ $id := $scratch.Get "divid" }}
{{ $chart_absolute_filename := $scratch.Get "absolute_filename" }}
<div class="echarts" data-filename="{{- $chart_absolute_filename -}}" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
{{- .Page.Scratch.SetInMap "this" "echarts" true -}}

Notice:

  • As soon as I replace .Inner with a string literal (e.g. ""), all works.
  • I only call the shortcode with a “file” parameter, so the branch with the .Inner mention is never actually triggered.

Any hint? Thanks!

That is “by design”. If you use .Inner in your code then Hugo expects your shortcode to have a closing tag. Using your file parameter you probably call only a single shortcode. You can’t :slight_smile:

What you can do is to close the shortcode.

{{< shortcode file="bla" >}}{{< /shortcode >}}

and then in your shortcode you trim accidental whitespace from .Inner so that you can check it with with .Inner.

{{ $inner := trim .Inner "\n " }}

PS: Your assumption that the “branch with the .Inner mention is never actually triggered” might be right, but you need to know that Hugo parses all templates and validates them. If you have an error in them even if they are not called they will result in errors/warnings/issues.

You can also use the self-closing syntax:

{{< shortcode file="bla" />}}

(hope I got that right).

3 Likes