docs: gate the prevnext chain on MediaWiki:Sidebar's order - #463
Conversation
The documentation pages are a sequence, and the sequence is written down
twice: as the order of MediaWiki:Sidebar, and as the arguments of the
{{prevnext}} call at the bottom of each page. Nothing checked that the two
agreed, and they had already drifted -- #446 put Writing an extension in the
sidebar and never wired it into the chain, which left Development, Writing an
extension and Licenses with no navigation at all, so a reader who took
Standalone binary's next step arrived at a page with no way onward and no way
back. #452 and #456 gave those three their calls by hand, and the tree agrees
today. What was missing is anything that keeps it agreeing.
So the sidebar becomes the order of record, and a step in lint.yml's docs job
derives from it the call each page should carry, then fails on a page carrying
a different one. It catches every shape the drift takes: a reordered sidebar, a
page added to the sidebar and not to the chain, a page inserted in the chain
without the page before it being told, a sidebar entry with no page under
docs/, and navigation on a page the sidebar leaves out.
A check rather than the derivation #455 proposed, because deriving the chain in
wikitext needs string work no parser function does, and both ways to get that
cost more than the duplication does. A Lua module needs a Scribunto engine, and
this image has one -- luasandbox is compiled into mediawiki:1.46-fpm-alpine,
which the issue could not assume -- but the standalone binary cannot: its PHP
is compiled from the extension list in binary.Dockerfile, and one static
executable offers no lua binary for the standalone engine either. The site that
documents the binary would stop being a site the binary can bake. A build step
writing a lookup page runs in both, but it is a wikven feature carried for one
site's docs, and it takes "where does this page lead" out of the page's own
source, where an editor reads it.
Development's continuous-integration section now names all three docs gates
rather than the one it listed before #452 added a second, and the template's own
documentation says where the order comes from and what holds the two copies
together.
Korean translation updated; every unit reports ok.
|
Closing without merging: the order is going to be made a single source of truth, and a check that keeps two copies agreeing is not a step toward that. It would make the duplication permanent by making it safe, which is the opposite of what #455 asks for. #455 stays open for the real thing. Two findings from this branch are worth keeping out of the bin, since neither depends on the check: Scribunto is available in the image but not in the standalone binary.
The tree state noted here is also worth recording: the sidebar's 19 entries and the prevnext chain agree entry for entry today. #452 and #456 closed the gaps the issue found, so what is left is only that nothing holds them together, which is exactly the part the single-source plan will do properly. 🤖 Generated with Claude Code |
The Development page lists what CI enforces, and said `lint.yml` checks that every configuration variable is documented. Since #452 it checks the build steps too, so the one page whose job is to describe the gates was out of date about them. Noticed while closing #463. Korean translation updated and restamped, so `translate check --gate` still reports everything up to date. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
Takes the middle option of #455 rather than its proposal, and says why below. Refs #455; it does not close it, since the order is still written down twice.
What the tree looks like now
The drift the issue documents has been repaired by hand in the meantime, so the starting point is different from the one it describes.
ExtensionsandCommandswere added to both the sidebar and the chain; #452 gaveDevelopmentandWriting an extensiontheir calls, and #456 gaveLicensesitsprev=. The 19 sidebar entries and the chain agree today, entry for entry, and the new check passes on the tree unchanged. What is still missing is anything that keeps them agreeing, which is the half of the issue this fixes.The check
One step in
lint.yml'sdocsjob, beside the two gates #452 added there. It readsdocs/MediaWiki:Sidebar.wikitextthe way the skin does (one page per**entry, with theSpecial:MyLanguage/prefix and the|message-keylabel cut off), prependsindex, then derives the exact call each position should carry and compares it with the one the page has: a next alone at the head,prev=alone at the tail, a previous and a next in between. It also fails on a sidebar entry with no page underdocs/, and on a page that carries navigation without being in the sidebar.indexstays the one-way head: the sidebar deliberately has no main-page entry, since every skin's logo leads there, so the first sidebar page keeps its next-alone call rather than gaining a← Wikvenlink. That is the shape the tree has, not a new decision.Why a check and not the derivation
Deriving prev and next inside wikitext needs the sidebar's lines split and its prefixes and labels stripped, which no parser function does. The two ways to get that both cost more than the duplication does.
A Lua module. The issue asked whether Scribunto runs in the image, and it does:
luasandboxis compiled intomediawiki:1.46.0-fpm-alpine, so that half of the trade is better than the issue assumed. The standalone binary is where it fails. Its PHP is compiled from the extension list inbinary.Dockerfile, which has noluasandbox, and one static executable cannot offer theluabinary the standalone engine wants either. The docs site would become a site the binary cannot bake, which is a strange thing for the site that documents the binary.A build step writing a lookup page. This runs in both products, and
build.phpalready generates{{Wikven software}}, so the shape exists. But it is a wikven feature carried for one site's documentation, it needs its own configuration, its own entry inConfigurationandDevelopment, and its own tests, and it moves "where does this page lead" out of the page source, which is where someone editing the page reads it.So the order stays written down twice, and the check moves the second copy from unwatched to watched. That is a smaller claim than #455 makes, and it is the honest one.
Also here
Development's continuous-integration section named one docs gate and there have been two since #452; it now names all three.Template:prevnext's own documentation gains a section on where the order comes from, since that is the file someone editing a call has open. Neither template page is exported, so that one is source-only documentation.Verified
The check was run against the tree at 76af705 (#446, before the repairs), where it reports exactly the three pages the issue names, with the call each one should have carried. It was also run against five synthetic drifts: two sidebar entries swapped, a page added to the sidebar and to itself but not to the page before it, a sidebar entry with no source file, and a
{{prevnext}}on a page the sidebar leaves out. Each fails with the position named; the unmodified tree passes.The docs site was baked locally with the image and the whole
smoke.ymlassertion step run over the output: it passes, including the<languages/>entry count derived from the source tree and the assertion thatSearching/ko's prevnext carries Translating's Korean title.translate checkin the image reports every translation up to date.CI is green,
smokeincluded. The two-bakes-identical assertion did fail on my machine, in the Korean Pagefind bundle alone and in no HTML file, which is #460 as #456 recorded it; it passed on the runner, so that non-determinism reads as intermittent rather than gone. Nothing here goes near it.