Page MenuHomePhabricator

Allow extensions to register custom form controls via extension.json attributes
Open, HighPublic

Description

Problem

CommunityConfiguration today bundles a fixed set of custom form controls (PageTitleControl, PageTitlesControl, NamespacesControl, CommonsFileControl, ...) directly in ext.communityConfiguration.Editor, registered in a local controls registry via rankRenderer( N, Control, tester ) [1]. Extensions that need a schema-specific control (e.g. lookup widgets for domain-specific IDs) currently have three options, none of them clean:

  1. Upstream the control into CC itself, coupling CC to extension-specific concepts (e.g. Wikifunctions ZIDs).
  2. Fork CC's Editor module
  3. Build out their own Special page outside CC and lose schema-validation history, and all the other CC affordances.

The first is how the existing PageTitleControl and CommonsFileControl got in, but those controls consume only MediaWiki-core and Commons concepts. For third-party extensions — WikiLambda, Wikibase, Growth, … — landing a domain-specific control in CC itself crosses an architectural boundary that the existing built-ins don't.

Use case motivating this

The Abstract Wikipedia team is migrating two WikiLambda-managed lists to CC (see T394410: Move management of recommended Wikifunctions to use CommunityConfiguration):

  • WikifunctionsSuggestions — a 5-entry list of recommended Wikifunctions shown in the {{#function:…}} VisualEditor dialog on client-mode wikis.
  • AbstractWikiSuggestedWikifunctions — a 10-entry list of HTML-returning Wikifunctions offered in Abstract Wikipedia's fragment menu.

Both providers currently validate ZIDs by regex (^Z[1-9]\d*$) and render in CC's default string-array editor, which means sysops type ZIDs blind with no autocomplete and no return-type safety net. The Wikifunctions search Action API already exposes a typed autocomplete — we'd like to plug that into the CC form instead of rebuilding it.

Proposed API

Add an attributes.CommunityConfiguration.Controls block to extension.json that maps a control ID to a ResourceLoader module + exported Vue component name:

"attributes": {
    "CommunityConfiguration": {
        "Controls": {
            "WikifunctionsFunctionLookup": {
                "module": "ext.wikilambda.functionLookup",
                "component": "FunctionLookupControl",
                "schemaControlName": "MediaWiki\\Extension\\WikiLambda\\Controls\\FunctionLookupControl"
            }
        }
    }
}

On the frontend, the DispatchRenderer/controls registry merges those extension-registered entries with the built-ins at registration time. When a schema property declares "control": "<schemaControlName>", CC lazy-loads the named RL module via mw.loader.using() before mounting the component in place of the default renderer.

The registered component would receive the same props as the built-in controls (modelValue, schema, etc.) and emit update:modelValue for CC's v-model binding, so the contract is identical to existing controls.

Acceptance criteria

  • Extensions can register custom Vue controls by adding an attributes.CommunityConfiguration.Controls.<ID> block, with no edits to CC's own tree.
  • Schema properties reference the custom control via the existing "control": "…" key (no new schema keyword).
  • Extension controls are lazy-loaded on demand (not bundled with CC's baseline editor module).
  • Jest coverage in CC exercises the renderer with a mock extension-registered control.
  • Zero regression in existing built-in controls.

Open questions for discussion

  • Should the extension-supplied module also be allowed to contribute a tester function (for ranked/fallback dispatch), or is direct mapping by schemaControlName sufficient?
  • Do we want to support control-level options in the schema (e.g. "control_options": { "outputType": "Z89" }) via a formal annotation, or leave option transport to control-specific conventions?
  • Should we allow extensions to override built-in controls, or reject that as too footgun-prone?

References

Event Timeline

Thanks for filing this @Jdforrester-WMF, I think it goes in alignment with the concept of UI schema we had think of to provide full customization of schema controls. The relevant task is a bit outdated, T370534: Decision on how UI schema abstraction should work but feel free to throw any feedback you may have here or there.

This request aligns with the team's current maintenance work focus so we'll discuss it with the team in our next refinement session (Wed).

Michael triaged this task as High priority.Tue, Apr 28, 3:58 PM
Michael moved this task from Needs Refinement to Current maintenance backlog on the Growth-Team board.
Michael subscribed.

Thanks! I concur that this gels well with our maintenance focus this quarter. But the open questions and how this interacts with our "UI schema" idea is beyond the scope of what we have for this in our backlog refinement meeting. Let's bring it to a different forum.

This request aligns with the team's current maintenance work focus so we'll discuss it with the team in our next refinement session (Wed).

Ack. (Or wherever you discuss!) Happy to help implement if that would move it over the line, but this should definitely be aligned first with what your team want it to deliver!