From 3c9b74674f198f14a6812e744329d9642cd6210f Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Fri, 7 Aug 2026 21:28:26 -0700 Subject: [PATCH 1/5] Restore gallery captions and items the conversion flattened Closes #52. A gallery is a flex row whose column widths come from `.gallery-cols-N figure`, so anything inside it that is not a figure gets no width from that rule and is laid out as one more item in the row. Three variants of that survived the conversion, and no gate could see any of them: every media check reasons about a URL, and misplaced content resolves and is linked exactly as correct content is. Each was verified against the captured live site before being changed rather than inferred from the markup, and the first is why that matters. Eleven captions in the FLAIR post were written as text trailing the last figure shortcode. Reading only the source, the obvious fix is to move the text into that figure's caption parameter, which is what the review suggested. The capture shows all eleven were blocks-gallery-caption elements, captions for the set, so that fix would have attributed a caption describing four images to whichever one sorted last and would have looked right. They move to a caption on the gallery instead. The other two were gallery items the conversion emitted as plain markdown, two bare images and eight linked ones, against li.blocks-gallery-item > figure in the original. Both become figure shortcodes, the linked ones through the parameter the theme already has, which puts the anchor back inside the figure where it was. The container becomes a figure, because figcaption is only valid as a figure's child. The reset already sets figure { margin: 0 } and the theme already styles figure > figcaption, so a set caption needed one rule: a full-width flex basis, without which it packs onto the end of the last row and reads as a caption for whichever image it lands beside. check-url-parity.py gains the gate that would have caught all of this, parsing the built pages rather than matching text, since nested figures defeat a regex. Demonstrated failing before being trusted: against the pre-fix content it reports 27 stray nodes and exits 1, and it distinguishes the shapes rather than counting them, naming bare text and each stray element type. The gate found more than the review did. The linked-image variant is on a post neither the review nor the issue mentioned, and it was found only by running the check across all 19 pages that carry a gallery. Verified through make-release.sh and against the local mirror: PASS - 1245 URLs honored, with assets at 1049 and orphans at 98, both unmoved, so no media was lost or newly orphaned by the rewrite. Co-Authored-By: Claude Opus 5 (1M context) --- assets/css/extended/custom.css | 10 +++ checks/README.md | 18 +++++ checks/check-url-parity.py | 75 +++++++++++++++++++ ...-a-supermicro-bpn-sas3-846el1-backplane.md | 4 +- .../06/21/moving-from-unraid-to-proxmox-ve.md | 16 ++-- ...ents-to-keep-room-temperatures-balanced.md | 44 +++++------ layouts/shortcodes/gallery.html | 16 +++- 7 files changed, 149 insertions(+), 34 deletions(-) diff --git a/assets/css/extended/custom.css b/assets/css/extended/custom.css index 4fe3fe5..c7c0eff 100644 --- a/assets/css/extended/custom.css +++ b/assets/css/extended/custom.css @@ -38,6 +38,16 @@ body { margin: 1rem auto; } +/* + The set caption is a flex item like the figures beside it, so without a full-width basis it + packs onto the end of the last row and reads as a caption for whichever image it lands next + to. Full width puts it on its own row under the set, which is what it describes. +*/ +.gallery > figcaption { + flex: 0 0 100%; + text-align: center; +} + .gallery-cols-1 figure { width: 100%; } diff --git a/checks/README.md b/checks/README.md index 435916f..83bc682 100644 --- a/checks/README.md +++ b/checks/README.md @@ -84,6 +84,24 @@ A count is all the check can observe, and two causes reach each direction: it ri **Both directions read absolute references as well as relative ones.** Hugo writes an absolute URL wherever a template resolves one against the base, which the entry-cover image on every list page does. Reading only rooted paths made those files look linked from nowhere while they were being displayed, and left a broken one unchecked in the other direction. The origin is read from the home page's canonical link rather than assumed, since staging and production build with different base URLs and a hardcoded host would check one environment's output against another's. No canonical link is a hard failure, because a guessed origin inflates the orphan count by exactly the pages that use one. +## The gallery check, which no direction above can reach + +Every check above reasons about a URL: whether it renders, whether it resolves, whether anything points at it. Content misplaced **inside** a gallery satisfies all of that. The file exists, the reference resolves, and something links it, so the media surface is green in both directions while the page is laid out wrong. The defect is one of structure, which is why three variants of it survived the conversion and every gate since. + +A gallery is a flex row whose column widths come from `.gallery-cols-N figure`. Anything in there that is not a `figure` gets no width from that rule and is rendered as one more item in the row. So the check reads the built pages and fails on any direct child of a gallery container that is not a `figure` or the gallery's own `figcaption`. + +The three shapes it found, all of them conversion artifacts, and each verified against the captured live site before being changed: + +| Shape in the markdown | What the old platform had | +| --- | --- | +| Caption text appended after the last `figure` shortcode's `}}` | `