Sandbox/Version demo: Difference between revisions
From OHC Network Wiki
More languages
More actions
Content deleted Content added
OHC identity seed |
OHC identity seed |
||
| (One intermediate revision by the same user not shown) | |||
| Line 4: | Line 4: | ||
|title=Version Demo |
|title=Version Demo |
||
|order=999 |
|order=999 |
||
|introduced= |
|introduced=4.0 |
||
}} |
}} |
||
{{Info|title=Sandbox demonstration|1=This page demonstrates the wiki's '''copy-on-write versioning + Cargo/SMW stack''' as a replacement for Docusaurus's versioned documentation model. Use the '''version dropdown''' in the badge strip above to navigate between versions — or read on for the full comparison.}} |
|||
This is a '''sandbox page''' demonstrating the wiki's copy-on-write versioning system. It is not real documentation. |
|||
== The problem with Docusaurus versioning == |
|||
== How it works == |
|||
When you run <code>npm run docusaurus docs:version 3.1</code>, Docusaurus copies the '''entire''' <code>docs/</code> tree into <code>versioned_docs/version-3.1/</code>. For the CARE documentation: |
|||
{{Info|title=Version history|1=This page was "introduced in 2.0". A frozen fork exists at [[Sandbox/Version demo/1.0]] representing the old v1.0 content. The version-switcher pills below the title are auto-generated from that subpage via a Cargo query.}} |
|||
* 98 pages per version |
|||
The versioning model: |
|||
* 2 versions (3.0, 3.1) = '''196 files''' committed to git |
|||
* Actual content difference between 3.0 and 3.1: '''zero bytes''' |
|||
Every edit to the "latest" docs must be manually backported (or not) to older versions. There's no query for "what changed" — you <code>diff</code> two directories. Navigation is hard-coded in <code>sidebars.js</code> files that must also be duplicated. |
|||
# '''Canonical page = latest.''' You are reading it now. |
|||
# '''Fork only on divergence.''' When content changes between releases, the old text is snapshotted to a subpage (<code>Page/1.0</code>) and marked <code>status=frozen</code>. |
|||
# '''Version switcher''' (rendered by <code><nowiki>{{Version switcher}}</nowiki></code>) queries Cargo for frozen subpages and shows clickable pills. |
|||
# '''Frozen banner''' on the old page links readers back here. |
|||
== |
== How this wiki solves it == |
||
=== Copy-on-write: fork only what diverges === |
|||
* '''On this page:''' look for the "Older versions: …" pill strip linking to <code>/1.0</code>. |
|||
* '''On the [[Sandbox/Version demo/1.0|frozen fork]]:''' look for the blue banner saying "You are viewing documentation frozen at …". |
|||
{| class="wikitable" |
|||
== Cleanup == |
|||
! Principle !! Implementation |
|||
|- |
|||
| '''Canonical = latest''' || You're reading it. One page, no prefixes, no duplication. |
|||
|- |
|||
| '''Fork on divergence''' || When content changes between releases, the old text is snapshotted to a subpage (<code>Page/3.0</code>) marked <code>status=frozen</code>. |
|||
|- |
|||
| '''Implicit version spanning''' || A page with <code>IntroducedIn=3.0</code> and empty <code>DeprecatedIn</code> is valid for 3.0, 3.1, 3.2, … — it doesn't need to be copied. |
|||
|- |
|||
| '''__NOINDEX__ on forks''' || Search engines only see the latest. No duplicate-content penalties. |
|||
|} |
|||
=== Global version dropdown (like Docusaurus navbar) === |
|||
This page and its subpage can be deleted once the demonstration is no longer needed. They are excluded from search via <code>__NOINDEX__</code> on the frozen fork and categorized under [[Category:Sandbox]]. |
|||
The dropdown in the badge strip above is injected by <code>MediaWiki:Common.js</code> on every page with <code><nowiki>{{Doc header}}</nowiki></code>. It: |
|||
# '''Persists''' your version choice in <code>localStorage</code> |
|||
# '''Auto-redirects''' on page load: if you've selected "3.0" and you navigate to a page that has a <code>/3.0</code> fork, you land there automatically |
|||
# '''Stays''' on the canonical page with a toast notification when no fork exists (because the content is unchanged) |
|||
# '''Works across the entire wiki''' — one global context, same as Docusaurus's URL-prefix approach |
|||
=== Cargo: structured version metadata === |
|||
Every page declares its version range in machine-readable Cargo fields. This enables: |
|||
'''Live query — all versions of this demo page:''' |
|||
{{#cargo_query:tables=Docs |
|||
|fields=_pageName=Page,IntroducedIn=Since,DeprecatedIn=Until,Status |
|||
|where=_pageName LIKE 'Sandbox/Version demo%' |
|||
|order by=IntroducedIn |
|||
|format=table |
|||
}} |
|||
'''What would "what's new in 4.0?" look like?''' |
|||
{{#cargo_query:tables=Docs |
|||
|fields=_pageName=Page,DocType=Type,Domain |
|||
|where=IntroducedIn='4.0' AND Status='current' |
|||
|format=table |
|||
|default=''(No real CARE pages are tagged 4.0 — this query would populate automatically when 4.0 ships.)'' |
|||
}} |
|||
In Docusaurus, answering "what changed in 3.1" requires diffing two directories of 98 files. Here it's one Cargo query. |
|||
=== SMW: automatic relationship graphs === |
|||
The <code><nowiki>{{Related}}</nowiki></code> template at the bottom of every doc page uses Semantic MediaWiki inverse queries. If page A declares <code>reference=Page B</code>, then page B's Related section '''automatically''' lists page A — no manual maintenance, no stale cross-references. Docusaurus has <code>onBrokenLinks: throw</code> at build time; we have '''live bidirectional links''' that never go stale because they're computed at render time. |
|||
== Head-to-head comparison == |
|||
{| class="wikitable" |
|||
! Dimension !! Docusaurus !! This wiki |
|||
|- |
|||
| '''Storage per version''' || Full tree copy (O(n × versions)) || Fork only diverged pages (O(changed)) |
|||
|- |
|||
| '''4 versions, 100 pages, 5 changes per version''' || '''400 files''' || '''115 pages''' (100 canonical + 15 forks) |
|||
|- |
|||
| '''Our actual case''' (98 pages, 3.0 ≡ 3.1) || 196 files (all identical) || '''98 pages''' (zero forks needed) |
|||
|- |
|||
| '''Global version dropdown''' || Built-in (navbar) || ✅ <code>MediaWiki:Common.js</code> (localStorage + auto-redirect) |
|||
|- |
|||
| '''Version persistence''' || URL path prefix (<code>/3.0/docs/...</code>) || localStorage (survives navigation, no URL noise) |
|||
|- |
|||
| '''"What changed in X?"''' || <code>diff -r</code> two directories || One Cargo query: <code>WHERE IntroducedIn='X'</code> |
|||
|- |
|||
| '''Cross-references''' || Relative paths; break silently without CI || SMW inverse queries; always current, never stale |
|||
|- |
|||
| '''Navigation/sidebar''' || Hand-maintained <code>sidebars.js</code> (duplicated per version) || Cargo query: <code>WHERE DocType='concept' ORDER BY Domain, SidebarOrder</code> |
|||
|- |
|||
| '''Broken link detection''' || Build-time (<code>onBrokenLinks: throw</code>) || '''Impossible by design''' — links are queries, not hard paths |
|||
|- |
|||
| '''Searchability of metadata''' || None (frontmatter is build-only) || Full: <code>Special:CargoTables</code>, <code>Special:Ask</code>, API queries |
|||
|- |
|||
| '''Edit workflow''' || PR → merge → rebuild → deploy || Edit in browser (or push.py) → live in seconds |
|||
|- |
|||
| '''i18n''' || Separate <code>i18n/</code> tree per locale || Translate extension: per-paragraph, tracks staleness |
|||
|- |
|||
| '''Release process''' || <code>npm run docs:version X</code> (copies everything) || Fork only changed pages + update one JS line |
|||
|- |
|||
| '''Structured field data''' || Markdown tables (not queryable) || Cargo <code>ModelField</code> table: 500 fields across 35 models, queryable |
|||
|- |
|||
| '''Glossary''' || None || Lingo extension: hover-definitions site-wide from one page |
|||
|} |
|||
== The version demo in action == |
|||
This page has '''three frozen forks''' showing progressive evolution: |
|||
* [[Sandbox/Version demo/1.0]] — email only, sync, 2 config variables |
|||
* [[Sandbox/Version demo/2.0]] — async + multi-channel + preferences |
|||
* [[Sandbox/Version demo/3.0]] — templates + tracking + push + batching + live Cargo table |
|||
Each fork only stores '''its own content''' — not copies of every other page in the wiki. The version dropdown lets you navigate between them exactly like Docusaurus's version picker, but without the storage explosion. |
|||
== Storage comparison (this demo) == |
|||
{| class="wikitable" |
|||
! Versions !! Docusaurus model !! Wiki model !! Savings |
|||
|- |
|||
| 1.0 || 1 full copy || 1 page (canonical at the time) || — |
|||
|- |
|||
| 2.0 || 2 full copies || 1 canonical + 1 fork || 50% |
|||
|- |
|||
| 3.0 || 3 full copies || 1 canonical + 2 forks || 67% |
|||
|- |
|||
| 4.0 || 4 full copies || 1 canonical + 3 forks || 75% |
|||
|- |
|||
! colspan="2" | At scale: 100 pages × 10 versions !! !! |
|||
|- |
|||
| (assuming 10% changes per release) || '''1000 files''' || '''190 pages''' (100 + 90 forks) || '''81%''' |
|||
|} |
|||
== Release checklist (vs Docusaurus) == |
|||
=== Docusaurus === |
|||
<syntaxhighlight lang="bash"> |
|||
# 1. Copy entire tree (even unchanged pages) |
|||
npm run docusaurus docs:version 4.1 |
|||
# 2. Update versions.json |
|||
# 3. Duplicate sidebars.js |
|||
# 4. Rebuild and deploy |
|||
npm run build && npm run deploy |
|||
# Total: hundreds of files touched, full CI/CD cycle |
|||
</syntaxhighlight> |
|||
=== This wiki === |
|||
<syntaxhighlight lang="bash"> |
|||
# 1. For each page that ACTUALLY CHANGED: |
|||
# - Copy current content to Page/4.0 subpage (mark frozen) |
|||
# - Update canonical page with new content |
|||
# 2. Update one line in MediaWiki:Common.js: |
|||
# KNOWN_VERSIONS = [ '4.1', '4.0', '3.1', ... ]; |
|||
# 3. Done. No build step. No deploy. Live immediately. |
|||
</syntaxhighlight> |
|||
== Try it yourself == |
|||
# '''Use the dropdown above''' — select "3.0" and you'll be taken to [[Sandbox/Version demo/3.0|the frozen 3.0 page]]. |
|||
# '''Navigate to another page''' (e.g. [[Concepts/Patient]]) — the dropdown shows your stored preference. Since Patient has no fork, you see a toast: "This page is unchanged in CARE 3.0". |
|||
# '''Select "4.0 (latest)"''' to return to the canonical view everywhere. |
|||
[[Category:Sandbox]] |
[[Category:Sandbox]] |
||