Issues with Scratch and maybe (?) caching

I have a site I’m working on where I assemble one page’s table of contents using scratch. Basically the structure of the template is roughly like this:

<!-- layouts/docs/baseof.html -->
{{ partial "docs/content.html" . }} <!-- The page's content -->
{{ partial "docs/toc.html" . }} <!-- The table of contents -->

Inside the page’s .Content block (i.e. the page’s Markdown) there are some shortcodes I created that manipulate the page’s Scratch:

<!-- layouts/shortcodes/category.html -->
{{ $.Page.Scratch.Add "categories" (slice .category) }} <!-- .category is set in the shortcode -->

Then the TOC accesses it:

<!-- layouts/partials/docs/toc.html -->
{{ $categories := .Page.Scratch.Get "categories" }}

{{ range $categories }}
<!-- Build some HTML -->
{{ end }}

The problem is that works sometimes. If I run hugo server it’s usually working fine when I first load the page. But then I’ll update the page template or make some other change and the TOC will just disappear. I’ve tried using partialCached for the partial, I’ve tried using flags like --disableFastRender and --ignoreCache, pretty much all my usual tricks when something isn’t quite working. But I can’t seem to get past this.

Does this ring a bell to anyone?

There’s no guarantee that these partials will be rendered in sequence. Try this:

{{ $noop := .Content }}
{{ partial "docs/content.html" . }} <!-- The page's content -->
{{ partial "docs/toc.html" . }} <!-- The table of contents -->

However, even when doing something like this, I frequently have to restart hugo server after modifying the related templates to see the changes. If I change the content the changes are picked up right away.

3 Likes

After reading your post again, I think you might have to place {{ $noop := .Content }} inside of docs/toc.html.

@jmooring Sigh. That’s a bummer but it does make sense given how Hugo processes things. One of the drawback to that jet engine speed, I suppose :grinning_face_with_smiling_eyes:

I did try the $noop method you suggested, which is quite clever, but alas, it doesn’t seem to move the needle, even when I put it inside the toc.html partial. Oh well. I think it’s something I can live with :man_shrugging:

Is the content inconsistent from run-to-run of hugo (check contents of public directory), or is it inconsistent only when running hugo server? If the later, is the content correct when you start hugo server? What changes do you make before the content becomes inconsistent?

As I mentioned earlier, I frequently have to restart hugo server after modifying the related templates, but if I leave the templates alone everything is fine.

@jmooring As far as I can tell it’s working just fine when I’m not running server and it does always seem to work at first. It does introduce a wrinkle into the dev experience but as long as my live site is being built as expected it’s something I can work around.

1 Like

This is important for both scenarios.

@jmooring Basically if I’m not running server then the $noop solution doesn’t appear to be necessary, as far as I can tell, because the site always builds like I’d expect. When I am running server, though, it doesn’t seem to make a difference, no matter where I use it—the TOC renders fine when I first start the server and subsequent changes make it disappear. So there’s a certain je ne sais quoi about that initial build.

So the “solution” I went with here was to just use a JavaScript library (Tocbot) rather than trying to build the TOC manually. I was really hoping to use Hugo for the TOC but I’m just not seeing a way around this. Fingers crossed this gets addressed at some point, but no biggie if not, I’m content.