From 515074445feb67022d89741b994b369c15644c2a Mon Sep 17 00:00:00 2001 From: John Coffey Date: Mon, 2 Nov 2026 14:07:18 -0700 Subject: [PATCH] Manual: name console pages by the menu people see MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build-manual.mjs read the server's own layout, but the console regroups Settings on the client, so the reference named menus that no longer exist, such as Settings › TLS › Certificates for what the console shows as Settings › Security › Certificates. It now applies withRegroupedSettings before walking the menus. A page reads as Settings › category › page, the way most guides write it; the group stays as a heading in the reference index. Page titles come from the same menu labels, so they follow the console's wording too. Pages the old layout didn't list, such as Branding, gain a location line. File names and anchors are unchanged, so "Learn more" links keep working. --- tools/build-manual.mjs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tools/build-manual.mjs b/tools/build-manual.mjs index 984a37e..4316a9a 100644 --- a/tools/build-manual.mjs +++ b/tools/build-manual.mjs @@ -45,6 +45,7 @@ const { FIELD_HELP, PAGE_HELP } = await vite.ssrLoadModule('/src/help/texts.ts') const { describeDefault } = await vite.ssrLoadModule('/src/help/defaults.ts'); const { humanize } = await vite.ssrLoadModule('/src/lib/humanize.ts'); const { manualPage } = await vite.ssrLoadModule('/src/help/manual.ts'); +const { withRegroupedSettings } = await vite.ssrLoadModule('/src/lib/settingsLayout.ts'); await vite.close(); const WORDS = { on: 'On', off: 'Off', none: 'None' }; @@ -87,7 +88,16 @@ function walk(items, path) { } } } -for (const layout of schema.layouts) walk(layout.items, [layout.name].filter(Boolean)); +// The menus as the console shows them: Settings is regrouped client-side, so the +// server's own layout names groups nobody sees. +for (const layout of withRegroupedSettings(schema).layouts) walk(layout.items, [layout.name].filter(Boolean)); + +// Settings › category › group › page reads as the category and the page, the way +// the guides write it; the group is only a heading in the category's menu. +function whereWords(where) { + const path = where[0] === 'Settings' && where.length === 4 ? [where[0], where[1], where[3]] : where; + return path.map(md).join(' › '); +} // --- What a field holds, in words -------------------------------------------- @@ -223,7 +233,7 @@ function fieldEntry(scope, f) { function schemaPage(name) { const lines = front(title(name)); const where = whereInConsole.get(name); - if (where) lines.push(`*In the console: ${where.map(md).join(' › ')}*`, ''); + if (where) lines.push(`*In the console: ${whereWords(where)}*`, ''); const text = about(name); if (text) lines.push(sentence(md(text)), ''); @@ -261,7 +271,7 @@ function ownPage(name) { const help = PAGE_HELP[name]; const lines = front(title(name)); const where = whereInConsole.get(name); - if (where) lines.push(`*In the console: ${where.map(md).join(' › ')}*`, ''); + if (where) lines.push(`*In the console: ${whereWords(where)}*`, ''); if (help?.about) lines.push(md(help.about), ''); for (const option of help?.options ?? []) { lines.push(`### ${md(option.label)}`, '', md(option.text), ''); -- 2.54.0