$.Scratch sometimes has empty data in development mode

$ hugo version
hugo v0.98.0-165d299cde259c8b801abadc6d3405a229e449f6+extended windows/amd64 BuildDate=2022-04-28T10:23:30Z VendorInfo=gohugoio

layouts/_default/baseof.html

{{- $.Scratch.Set "gloablvar" "value" -}}

index.html

{{- $paginator := .Paginate (where site.RegularPages "Type" "in" (slice "posts" "status")) -}}
{{- range $paginator.Pages -}}
    {{- partial "post-card" .}}
{{end}}

layouts/partials/post-card.html

{{- $gloablvar := $.Scratch.Get "gloablvar" -}}
<div>{{- $gloablvar -}} <br> {{- $.Scratch -}}</div>

output

{map[gloablvar:value] {{0 0} 0 0 0 0}}

When the development server is started for the first time it works fine, but after a while the following situation will occur.

<div><br>{map[] {{0 0} 0 0 0 0}}</div>

There are many “post-cards” on the page, but not every one of them is empty data

I haven’t studied your entire post, but I’m giving a qualified guess, here.

There is a long story to this, but the short one is this: When running the server, we clear the Page.Scratch when we rebuild, and this may have some unwanted side-effects.

We recently added $.Store.Set etc. which behaves exactly like Scratch, but is never cleared.

1 Like

It looks great, but there doesn’t seem to be any more detail in the documentation, is it in beta status?

I have set $.Store.Set ... in layouts\_default\baseof.html

In layouts\_default\_markup\render-image.html, in development mode $.Store.Get ... first render is nil

I think the problem may be caused by the rendering order.

So where should I set a global variable

Not in beta, but there are some missing pieces in the docs. I’m in the process of redoing the documentation site with a complete reference section.

Using Scratch in different places requires you to think a little:

  • Hugo renders pages in parallel, so there is no guarantee that, say, the home page gets rendered before any other.
  • If you want to access a scratch value in a render hook you need to make sure to set it before any of the content methods gets called (e.g. {{ $.Store.Set "foo" "bar" }} {{ $tmp := .Content }}. I don’t have your source code, so I have no idea about the details here.

One trick that can be used to overcome some this is to set up a output format that prepares some global state (in e.g. the home page template) and make sure that is ordered first (either by prefixing it with e.g. _ or set a weight on the output format definition). That way you will be guaranteed to not have multiple threads/goroutines mixing up…

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