.Page.Scratch is empty in _default/_markup/render-heading.html

This:

<p>scratch: {{ .Page.Scratch }}</p>

Renders as this for a page:

scratch: {map[paige_show_full_pages:true] {{0 0} 0 0 0 0}}

But renders as this in _default/_markup/render-heading.html for the same page:

scratch: {map[] {{0 0} 0 0 0 0}}

I use a scratch variable to control whether headers are linked in page content, so they can be linked in single pages, but not in list pages.

Info:

$ hugo env
hugo v0.108.0+extended darwin/amd64 BuildDate=unknown
GOOS="darwin"
GOARCH="amd64"
GOVERSION="go1.19.3"
github.com/sass/libsass="3.6.5"
github.com/webmproject/libwebp="v1.2.4"

Where are you setting the scratch?

I suppose you set the scratch right before invoking the .Content in the template…

{{ range .Pages }}
  {{ .Title }}
  {{ .Scratch.Set "list" true }}
  {{ .Content }}
{{ end }}

I could be wrong but as Hugo builds its pages concurrently it does not guarantee that this Scratch data will be on the page at the moment you wish it does.

The above will work, but not if you somewhere else call .Content on that same page, which I suspect is the problem here (e.g. in some list template).

1 Like

Where are you setting the scratch?

I suppose you set the scratch right before invoking the .Content in the template…

Yes:

{{ if .Pages }}
{{ if .Params.paige.show_full_pages }}
{{ $p := .Paginate .Pages }}
{{ range $p.Pages }}
{{ .Scratch.Set "paige_show_full_pages" true }}
{{ partial "paige/article" . }} {{/* uses .Content /*}}

Note that the scratch variable is present if I use the regexp search/replace trick for header links instead of a header render hook by doing something like this in the partial template included in the for loop:

{{ if .Scratch.Get "paige_show_full_pages" }}
{{ .Content }}
{{ else }}
{{ .Content | replaceRE `(<h[1-6] id="([^"]+)".+)(</h[1-6]+>)` `${1}<a class="paige-header-link" href="#${2}">#</a>${3}` | safeHTML }}
{{ end }}

The above will work, but not if you somewhere else call .Content on that same page, which I suspect is the problem here (e.g. in some list template).

I expected the render template to be invoked when .Content is evaluated, so the scratch variable would be there. Is that not the case?

Edit: Added missing paige_show_full_pages logic in last example.

@bep @jmooring Sorry, I’m not clear on whether Discourse emails participants about new comments, so tagging you here since there’s been no reply, just in case it doesn’t email.