Skip to content

Add an on-wiki JSON configuration page at MediaWiki:NeoWiki - #1139

Merged
malberts merged 2 commits into
masterfrom
feature/on-wiki-config
Jul 23, 2026
Merged

Add an on-wiki JSON configuration page at MediaWiki:NeoWiki#1139
malberts merged 2 commits into
masterfrom
feature/on-wiki-config

Conversation

@JeroenDeDauw

@JeroenDeDauw JeroenDeDauw commented Jul 23, 2026

Copy link
Copy Markdown
Member

Add an on-wiki JSON configuration page at MediaWiki:NeoWiki

A wiki administrator without server access can set a vetted subset of NeoWiki's configuration on the
MediaWiki:NeoWiki page. It holds JSON and is forced to the JSON content model on exactly that title, so
MediaWiki gives it editinterface + editsitejson edit protection, JSON syntax enforcement, and the JSON
editor for free. Set $wgNeoWikiEnableInWikiConfig to false to disable it entirely: the page is then
never given the content model, validated, or read.

Builds on the merged #1141 (the boolean $wgNeoWikiDereferenceSubjectsToDataTab rename); the branch is a
single commit on current master. Both exposed settings are boolean.

Exposed settings (the allowlist is the security boundary)

Page key Overrides Accepts
dereferenceSubjectsToDataTab $wgNeoWikiDereferenceSubjectsToDataTab true | false
autoRenderMainSubject $wgNeoWikiAutoRenderMainSubject true | false

Every other setting stays exclusive to LocalSettings.php, deliberately: NeoWikiSparqlStores is
infrastructure and carries secrets (secrets never go on-wiki); NeoWikiRdfBaseUri re-mints every IRI when
changed, too consequential for a wiki page; NeoWikiEnableDevelopmentUI is dev-only. Future settings are
vetted and added one at a time.

Precedence and failure semantics

Per setting, a valid value on the page wins; otherwise the LocalSettings.php value (itself the
extension.json default) applies. A missing page, unparseable JSON, a value of the wrong shape, or an
unavailable database all fall back to LocalSettings.php rather than throwing — a config typo must not take
down the wiki (the NeoWikiConfigFactory stance). The read path is tolerant and forward-compatible: unknown
keys are ignored, and one NeoWiki-channel warning is logged when the page exists but a value (or the whole
document) is unusable. The page is read at most once per request (memoized on a request-scoped source) and
never during extension registration.

Saving is strict: an EditFilter rejects non-object JSON, unknown keys, and wrong-typed values with precise,
i18n'd, per-field errors, so a typo is caught where the admin can fix it.

One schema structure (ConfigSchemaConfigSetting) defines each key once and drives save validation, the
generated on-page reference table, and the preloaded example, so they cannot drift. A test pins the preloaded
example against the validator.

The two existing consumers now read through the combining lookup:
ResolveSubjectIriApi::dataTabDereference() and NeoWikiExtension::shouldAutoRenderMainSubject(), each as a
strict boolean. Their existing contracts hold whichever source supplied the value.

Documentation affordances (that title only, kill-switch-gated)

  • Editing suppresses the default MediaWiki-namespace intro and frames the JSON editor with a one-line docs
    pointer and the schema-generated reference table (page key | accepted value | LocalSettings.php setting).
    The key and setting columns are plain text; the accepted value shows the literal JSON values (true /
    false) as <code> spans.
  • Viewing shows the same pointer and reference around the core JSON table.
  • Creating preloads a small valid example covering both settings.

Parser-cache staleness

dereferenceSubjectsToDataTab is read at request time, so it takes effect immediately. autoRenderMainSubject
affects rendered page HTML, so already-cached pages keep their previous rendering until they re-parse (or a
?action=purge) — accepted, and stated in the docs.

Alternatives considered and rejected

  • CommunityConfiguration (extension): a schema-driven config framework with a generated form UI. Rejected
    as the primary mechanism: it is a dependency, and form-first where NeoWiki wants a small JSON-first page with
    no new dependency. It stays composable — PHP/LocalSettings remains authoritative underneath, so a form layer
    could sit on top later.
  • BlueSpice ConfigManager: the distribution's own config UI. Same shape (form-first, distribution-specific).
    NeoWiki must work on plain MediaWiki, and the JSON page composes under any such layer since the values still
    resolve through the same PHP settings.

Considered, omitted

  • A ConfigType class hierarchy (Maps ships twelve): unwarranted here. Both exposed settings are boolean, so
    ConfigSetting fixes the value shape directly with no discriminator; the enum machinery (and its
    ConfigValueType) was dropped when the dereference target became boolean, and is re-added with the first
    genuinely differently-shaped setting.
  • A visual/form editor: the JSON page plus the generated reference is enough; a form layer can compose on top.
  • Folding the combined values onto the NeoWikiConfig value object: kept separate and lazy so the eager config
    VO never triggers a DB read and behavioural settings stay overridable in tests without a singleton rebuild.

Ported from the Maps extension's MediaWiki:Maps pattern (PRs ProfessionalWiki/Maps#925 and #928), scaled to
two settings and NeoWiki's hexagonal layering.

AI-authored — Claude Code, Opus 4.8 (max); detailed spec from @JeroenDeDauw plus a two-change review follow-up; not yet human-reviewed (an earlier AI correctness/security + design pass caught and fixed a blocking EditFormPreloadText null-$text fatal, with a regression test). Rebased to a single commit on master after #1141 merged; both settings are boolean and the enum machinery is removed. Full PHPUnit (2018) + phpcs + phpstan green; CI green; live re-verified on a dev wiki (restyled reference table, page-wins dereference to the Data tab, save rejection, kill-switch).

@JeroenDeDauw
JeroenDeDauw marked this pull request as ready for review July 23, 2026 15:51
@JeroenDeDauw

Copy link
Copy Markdown
Member Author
image

A vetted subset of NeoWiki configuration (dereferenceSubjectsToDataTab,
autoRenderMainSubject) becomes settable on the MediaWiki:NeoWiki JSON page:
strict save-time validation, per-setting page-wins-over-LocalSettings combining
with never-throw fallback, schema-generated on-page reference, preloaded
example, and a kill-switch.

Squash of the reviewed branch after master gained the boolean dereference
setting (#1141) the branch already contained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
onConfigPageBeforePageDisplay reduced the config page to its JSON table on
every 'view' action. A diff request (?diff=) also resolves to the 'view'
action, so the comparison table was discarded and replaced by the framed
current revision; guard against it so diffs of MediaWiki:NeoWiki render
normally.

The trim also took everything from the mw-json table to the end of the body.
Core wraps that table in <div class="noresize">, so the slice re-emitted the
wrapper's orphaned closing </div>, leaving the framed view with unbalanced
HTML (the reference block escaped #mw-content-text). Extract the balanced
<table>...</table> element instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@malberts
malberts merged commit 7077681 into master Jul 23, 2026
6 checks passed
@malberts
malberts deleted the feature/on-wiki-config branch July 23, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants