Question: is `page` supposed to work inside of a shortcode?

Once Hugo evaluates a page’s content, the content is cached, as it should be.

The following page variables force evaluation of a page’s content:

  • Content
  • FuzzyWordCount
  • Len
  • Plain
  • PlainWords
  • ReadingTime
  • Summary (regardless of how you define it)
  • Truncated
  • WordCount

So if you do this on a list page (and you do)…

{{ range .Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
  {{ .Summary }}  <-- FORCES CONTENT TO BE EVALUATED AND CACHED
{{ end }}

… each page’s content is evaluated and cached when building the list page.

And within each iteration, the page function is the context of the top level page in the template (in this case, the list page).

So, if each page calls a shortcode like this…

{{ with page.Resources.Get "cover.jpg" }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}

… then page.Resources.Get isn’t going to find anything—it’s looking for resources associated with the list page. It all depends on whether the regular page is rendered (and cached) before the list page, but with concurrency that’s out of your control. In short, the results are unpredictable.

Use .Page.Resources.Get in your shortcode.


As @pamubay pointed out, you need to be really careful about how you use the page function. My favorite example:

layouts/home.html

{{ range site.Sections }} <-- 3 sections
  {{ range .Pages }}  <-- 10 pages in each section
    {{ page.Title }}
  {{ end }}
{{ end }}

This will print the title of content/_index.md (the home page) 30 times. Probably not you want.