From fe92db567ff4685ba15ebb24af9d9a7f1c60bb8a Mon Sep 17 00:00:00 2001 From: Mark Dumay <61946753+markdumay@users.noreply.github.com> Date: Thu, 30 Jul 2026 19:35:16 +0200 Subject: [PATCH] fix(section): honour a per-block padding override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `cta` and `panels` both declare `padding` in their bookshop schema, so authors set it and reasonably expect the section's vertical padding to change. It never did. `utilities/section.html` derived padding solely from `utilities/GetPadding.html`, which reads site parameters, and no block passed anything through. The key was accepted, range-validated, and dropped. Measured on a real site before this change: four `cta` blocks carrying `padding: 4` and seven carrying nothing all rendered `py-5`, and `padding: 0` rendered `py-5` too. After: `padding: 4` renders `py-4`, `padding: 0` renders `py-0`, and a block with no `padding` still renders the site default `py-5`. The horizontal axis (`px-3 px-md-5`) is byte-identical in every case. ## The empty default is load-bearing `padding` inherits the shared definition in mod-utils `data/structures/_arguments.yml`, which carries `default: 3`. Left alone, an omitted `padding` would arrive as 3 rather than nil — "not supplied" becomes indistinguishable from "supplied", and every section that does not set one gets silently repadded. An earlier revision of this change hit exactly that: unset `cta` blocks dropped from `py-5` to `py-3`. `data/structures/section.yml` therefore redeclares `padding` with an empty `default:`. `ArgsSchema.html` merges the local node over the global one, so the empty value wins and a real nil is restored. The inherited `options` (0-5) survive that merge, so validation is unchanged -- `padding: 9` still fails with "out of range [-, 5]" before rendering. The nil comparison is deliberate for the same reason: `with` or `| default` would discard a legitimate `padding: 0`. ## Scope Vertical axis only. `x` is the page gutter, shared by every section and also feeding the outer container, so a per-block override there would misalign that section against its neighbours. Any mobile `y` override is dropped alongside, since it derives from the site value being replaced. Limited to `cta` and `panels` -- the two blocks where `padding` was purely inert. `approach`, `articles`, `cards`, `team` and `testimonials` also declare it, but forward it to inner partials (card group, section title) where it already means something; making it drive section padding as well would change existing sites, which is a semantic decision rather than a bug fix. `pnpm test` passes: 40 pages, no errors. --- .../components/cta/cta.hugo.html | 1 + .../components/panels/panels.hugo.html | 1 + data/structures/section.yml | 13 +++++++++ layouts/partials/utilities/section.html | 27 +++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/component-library/components/cta/cta.hugo.html b/component-library/components/cta/cta.hugo.html index 2cd26f0..b2602bb 100644 --- a/component-library/components/cta/cta.hugo.html +++ b/component-library/components/cta/cta.hugo.html @@ -64,6 +64,7 @@ "component-name" "cta" "id" .id "raw" $raw + "padding" .padding "background" .background "width" .width "justify" .justify diff --git a/component-library/components/panels/panels.hugo.html b/component-library/components/panels/panels.hugo.html index d9ff94f..bb422ca 100644 --- a/component-library/components/panels/panels.hugo.html +++ b/component-library/components/panels/panels.hugo.html @@ -108,6 +108,7 @@ "component-name" "panels" "id" .id "raw" $raw + "padding" .padding "background" .background "width" .width "justify" .justify diff --git a/data/structures/section.yml b/data/structures/section.yml index fd4f2c8..14736fe 100644 --- a/data/structures/section.yml +++ b/data/structures/section.yml @@ -24,6 +24,19 @@ arguments: bookshop folder. raw: passthrough: + padding: + type: int + optional: true + default: + comment: >- + Overrides the section's vertical padding, replacing the site-wide `y` + value from the `padding` configuration. Accepts 0 through 5. Horizontal + padding is unaffected: it is the page gutter, shared by every section. + Falls back to the site setting when omitted. The empty `default:` above is + load-bearing: it overrides the `default: 3` this argument would otherwise + inherit from the shared definition in mod-utils, which would make an + omitted value indistinguishable from a supplied one and repad every + section. The inherited 0-5 range still applies. background: width: default: 12 diff --git a/layouts/partials/utilities/section.html b/layouts/partials/utilities/section.html index b9e3532..c399be2 100644 --- a/layouts/partials/utilities/section.html +++ b/layouts/partials/utilities/section.html @@ -18,6 +18,33 @@ {{ end }} {{- $padding := partial "utilities/GetPadding.html" -}} + +{{/* Optional per-section vertical padding override. + + The `padding` argument inherits the shared definition in mod-utils + `data/structures/_arguments.yml`, which carries `default: 3`. That default + would arrive whenever a caller omits the argument, making "not supplied" + indistinguishable from "supplied" and silently repadding every section. + `data/structures/section.yml` therefore redeclares `padding` with an empty + `default:`, which overrides the inherited one and restores a real nil. The + inherited `options` (0-5) still apply, so validation is unchanged. + + Compared against nil rather than tested for truthiness: 0 is a legitimate + value that `with` or `| default` would silently discard. + + The override replaces the y axis only. x is the page gutter — letting one + block change it would misalign that section against every other section on + the page, and it also feeds the outer container. Any mobile y override is + dropped along with it, since that value was derived from the site setting + the author is replacing; the override then applies at every width. */}} +{{- if ne $args.padding nil -}} + {{- $revised := dict "x" $padding.x "y" (int $args.padding) -}} + {{- if isset $padding "mobileX" -}} + {{- $revised = merge $revised (dict "mobileX" (index $padding "mobileX")) -}} + {{- end -}} + {{- $padding = $revised -}} +{{- end -}} + {{- $page := or $args.page page -}} {{- $embed := $args.embed | default false }} {{- $paddingTop := and $embed (eq $args._ordinal 0) }}