First of all many thanks for creating and supporting Hugo.
I am having some troubles with understanding the processing order of Hugo.
Basically I have a bit of code which should be ran once - at the very beginning of the Hugo build.
It has to process each page and add some data to that page’s Scratch:
{{/* process every page */}}
{{ range .Site.Pages }}
{{/* partial which adds some data to the page's scratch */}}
{{ partial "page/get-version-info" . }}
{{ end }}
I tried adding this to the theme’s /index.html but I noticed that not every page has the expected Scratch when processing them in their layout files (single.html, list.html etc).
What would be the best file to place this piece of code so that it is executed before processing any of the other layout files?
It’s been discussed before (and I’m sure someone will dig up the link and put below :-)):
One of the reasons Hugo is so fast is that we do lot of parallel processing.
We do, however, render the output formats serialized and in a deterministic order.
So, what you can do is to define a custom output format with a template for the home page that collect this info and define that to be the first one (by setting the weight).
Using a loop in a custom output layout for the home page (demo).
As the page is processed by its corresponding layout (demo).
Using a loop in a custom layout, which is used by a dedicated content page (demo). This page has the weight set such that it will be processed first.
Results
The last one (customLayout) gave the best results. It uses a markdown file to run the custom layout. By setting the _build options in the front matter the file itself doesn’t get rendered.
Markdown file
run-custom-layout.md:
---
title: Run custom layout
layout: custom-layout
weight: -9999
_build:
render: always
list: never
---
Layout file
_default/custom-layout.html:
{{/* custom layout to process scratch for each page */}}
{{ if eq (.Param "scratchProcessing") "customLayout" }}
{{ $total := newScratch }}
{{ $total.Add "total" 1 }}
{{ range .Site.Pages }}
{{ partial "add-scratch" (dict "ctx" . "order" ( $total.Get "total" )) }}
{{ $total.Add "total" 1 }}
{{ end }}
{{ warnf "\n\n --> scratch added to %v pages by custom-layout" ($total.Get "total") }}
{{ end }}
Using this approach the scratch data is available for most pages (in both page title and -very important- the recursive sidebar), but sometimes the sidebar still lacks a number here and there.