HUGO

.Page.Scratch.Set in shortcode; Get in template = Race condition?

I am trying to capture some content generated in my page, store it in the Page.Scratch, and then read it out in the template.

If I edit any of the files involved in this process, everything generates as expected. If I edit any other file, my Scratch ends up empty in the template.

From the .md file

{{<toScratch "callout">}}
{{<ipad-callout class="card-ipad-grey-small" title="Helpful Hints and Additional Resources">}}
These boxes include helpful hints and additional resources relevant to the page content throughout the course.
{{</ipad-callout>}}
{{</toScratch>}}

The toScratch shortcode simply saves to the pages scratch. The param is the key name of the scratch.

{{ .Page.Scratch.Set (.Get 0) .Inner }}

When all this ends up in the template:

        <div class="content-body">
                <div class="row">
                    <div class= "col-sm-8 col-md-9">
                        {{- .Content -}}
                    </div>
                    <div class="col-sm-4 col-md-3">
                        {{ $.Scratch.Get "callout" }}
                    </div>
                </div>
            </div>

I’ve read about rendering nested shortcodes inside->out, which I’m doing. I’ve also read about race conditions created by the parallel nature of Hugo. I suspect that this is what I’ve run into. Is there a better way to pass the content up to the template?

In your template you need to render .Content before accessing the .Scratch. Something like:

{{ $noop := .Content }}
{{ .Scratch.Get "callout" }}

I read about that as well. I was accessing them in the correct order anyway. I added the $noop bit to see if it changes anything. No love.

So I tried setting the Scratch in a partial instead of the shortcode. So page->shortcode->partial. And it seems to work. Can anyone explain why?

Page.md

{{<toScratch "callout">}}
{{<ipad-callout class="card-ipad-grey-small" title="Helpful Hints and Additional Resources">}}
These boxes include helpful hints and additional resources relevant to the page content throughout the course.
{{</ipad-callout>}}
{{</toScratch>}}

shortcodes/toScratch.html

{{ partial "toScratch"  (dict "pageScratch" .Page.Scratch "key" (.Get 0) "value" .Inner)  }}

partials/toScratch.html

{{ .pageScratch.Set .key .value }}

Spoke too soon. Still having same issue. Sometimes the Page Scratch is still defined in the template, but more often than not, it is empty.

Looking for ideas.

Broken in hugo v0.83.1 on both Mac and Windows.

Looks like a duplicate.

The shortcode apparently doesn’t always render when using hugo in server mode. When I do a full build, it is fine.

But the suggested fix in the linked issue (use .Content before accessing the .Scratch created by running content) don’t apply, as I was doing so already.

Still stumped.

This is a known issue, isolated to certain conditions when running hugo server, and it will probably get fixed at some point:
https://github.com/gohugoio/hugo/issues/8255