Site-wide Scratch?

Hello Community,

I am curious if there is a site-wide Scratch function? I have everything working as I would like, but it seems the $.Scratch is page-wide and not scoped to the entire site.

FWIW I am incrementing a value every time a post is encountered throughout the site and then using that (modded) value to access data from the .Site.Data collection.

It would be great to know if I am overlooking something obvious here to accomplish what I am trying to achieve as well.

Thank you in advance for any assistance,

If I’m understanding you correctly then you’d need JavaScript for this.

Ah good point… to clarify, I am wanting to increment this value every time a post is generated (in go-land :)).

I see. So you can count pages. For example:

<!-- all pages -->
{{ len .Pages }}

<!-- only posts -->
{{ len (where .Pages "Section" "post") }}

Correct, the .Pages returns the total collection of pages, thank you for your assistance @zwbetz.

What I am interested in is when a page is generated (or rendered) and at that time increment a site-wide variable, essentially storing a variable (or state) across all known pages that I can not only read, but write/set.

Scratch works perfectly but it seems to be page-centric and not site-wide.

Hmm yeah am not sure how to accomplish this with Scratch (if it’s even possible).

I’d recommend using my example above and tweaking the where to filter down to only the pages you want.

It also depends on what you’re storing in this global variable. I was assuming it was a count of all pages you cared about, but if it’s something else then yeah my example won’t fit your needs.

OK that is good feedback. I will try to see if I can better explain my scenario.

Imagine I have a partial, with the following expression peppered throughout my templates:

{{ partial "stateful-template" . }}

Where stateful-template looks like the following:

{{ .Scratch.Add "SiteIndex" 1 }}
{{ $index := mod (.Scratch.Get "SiteIndex") (len .Site.Data.MyCollection) }}
{{ .Scratch.Set "SiteIndex" $index }}
{{ with index .Site.Data.MyCollection $index  }}
{{ end }}

This works fine when I iterate on a particular page, but when another page is rendered, the index is reset, even if I use $.Scratch. This makes it seem that $.Scratch is page-wide and not site-wide.

Ideally there would be a $.Site.Scratch but this does not seem to exist. Which makes me suspect there is a much more obvious/preferred way to accomplish what I am aiming to achieve here.

Are you able to share your code? Or if you can’t, then create a small project that replicates your issue. It’d be much easier to help you this way. So that I and others can see the full picture.

I also would love a .Site.Scratch addition and created this issue a couple of weeks ago. Maybe your use case would add some value to it.


OK thank you for both of your help. Reading your replies and also of the GitHub issue made me think of this some more.

In fact, this is way simpler than I have made this.

What I really need is the index of the current page. That is, from the list of .Site.Pages what index is .Page ?

Knowing this will do exactly the same thing in an obviously simpler way.

FWIW I did try:

{{ index .Site.Pages .Page }}

But this results in an error: error calling index: cannot index slice/array with type *hugolib.Page

Ok this is really ugly, but works. :stuck_out_tongue:

{{ $current := $.Page.UniqueID }}
{{ $scratch := .Scratch }}
{{ $key := "ContextIndex" }}
{{ $scratch.Set $key 1 }}
{{ range $.Site.AllPages }}
	{{ $i := $scratch.Get $key }}
	{{ if $i }}
		{{ if eq .UniqueID $current }}
			{{ $scratch.Add $key -1 }}
			{{ $index := mod ($scratch.Get $key) (len $.Site.Data.MyCollection) }}
			{{ with index $.Site.Data.MyCollection $index  }}
			{{ end }}
			{{ $scratch.Delete $key }}
		{{ else }}
		{{ $scratch.Add $key 1 }}
		{{ end }}
	{{ end }}	
{{ end }}