List Layouts

_default/list.html is hardwired to paginate .Pages into a card grid — great for a blog index, wrong for a section that is really a single page with no children, sourced from a data/*.json file instead of child content.

layout = "list-plain"

Ship a section with title + .Content and nothing else — no pagination, no card grid, no taxonomy cloud — by setting layout in its _index.md front matter:

+++
title = "About"
layout = "list-plain"
+++

Hugo picks _default/list-plain.html over _default/list.html for that section. This is Hugo’s own template-selection mechanism (the layout front matter field) rather than a theme-specific param, because unlike headerType or menuType — which pick a partial included from within one fixed entry template — Hugo has no other way to choose between two candidate top-level list templates.

The Releases section on this exampleSite uses it: a page with no children, its content sourced from data/releases.json.

utils/data-items.html

The “does this data file have anything in it” check — .Site.Data.releases.items | default slice — is easy to end up hand-rolling at every call site that reads a data/*.json file shaped {"items": [...]}. utils/data-items.html is a returning partial for it:

{{ $items := partial "utils/data-items.html" "releases" }}
{{ if gt (len $items) 0 }}
  ...
{{ end }}

It resolves .Site.Data.<name>.items, defaulting safely to an empty slice when the data file or its items key doesn’t exist — callers check len() rather than testing for existence directly.

Conditional menu entries reuse this exact partial: the Press nav link above only renders because data/releases.json has items.