Page MenuHomePhabricator

no custom wikitext-template columns (!59)
Closed, ResolvedPublic

Description

Scope: Drop the custom-wikitext-template escape hatch in favour of a comprehensive, well-documented set of built-in Commons templates with a redesigned Templates-tab UI.

Why: "Custom wikitext-template" requires the user to know template syntax — there's no good UX for it. Every template Commons cares about is enumerable, so the right move is to enumerate them all and expose them as first-class options.

What needs to change

1. Remove all "custom wikitext-template" surface area:

  • Delete the Custom template radio-card option from the Templates tab (src/columns-modal.jsx:537-543).
  • Delete the inline + Add custom wikitext-template column form (CustomColumnCreator) at the bottom of the Columns tab (src/columns-modal.jsx:307-312, 332-422).
  • Delete the Custom wikitext-template column entry-point from the new "+ Add column" popover (AddColumnPopover at src/table.jsx:4912-4922 on branch feat/T426421-new-column-button / MR !49).

2. Add the missing templates so the Templates tab covers all primary file-description templates Commons uses. Currently 4 (Information, Artwork, Photograph, Book — see src/wikitext-templates.js:40-153); should add: Map, Art photo, Specimen, Musical work. Each needs:

  • Entry in BUILTIN_TEMPLATES with all named parameters from its docs page.
  • fields[] mapping each param to the matching workbench column key (or key: null if the workbench has no equivalent).
  • requiredColumns + recommendedColumns.

3. Redesign the Templates tab from cards to expandable list:

  • Each list row: template name (e.g. {{Map}}) + one-line use-case description.
  • Click → expand to show: live wikitext preview block (already computed by renderTemplateBlock), per-param table mapping template_param ↔ workbench column with visibility checkmark, "Open Commons docs" link to https://commons.wikimedia.org/wiki/Template:<Name>.
  • Order rows by prevalence: Information > Photograph > Artwork > Book > Map > Art photo > Specimen > Musical work.

4. Surface field-level documentation:

  • In the expanded row, show per-param required/optional badge + the docs page's one-line "expected value" hint (e.g. ISO 8601 for date).
  • Per-param docs anchor: Template:<Name>#<param>.
  • Best-effort enforcement: where the workbench has a structured column (e.g. dateTaken is a date input, objectLocation is a coords pair), the existing column editor is the constraint. Free-text columns stay free-text.

5. Back-compat:

  • Users with stored wikitextTemplate = { id: 'Custom', body, fields } in User:<self>/UploadWorkbench/Preferences.json: silently fall back to Information on load. Don't crash; don't drop their custom body without warning.
  • Users with customProps of kind: 'template' (custom-wikitext columns saved as table columns): see Q-2 in the maintainer-question comment.

Where in the code

ConcernFile / range
Template registrysrc/wikitext-templates.js:40-153 (BUILTIN_TEMPLATES)
Custom template fallbacksrc/wikitext-templates.js:229-244 (resolveTemplate)
Templates-tab UI (cards)src/columns-modal.jsx:447-667 (TemplatesPanel, TemplateOption)
Custom-column creator (inline form)src/columns-modal.jsx:307-312, 332-422 (CustomColumnCreator)
"+ Add column" popover entrysrc/table.jsx:4912-4922 on branch feat/T426421-new-column-button (not yet on main)
Wikitext rendering (downstream)src/api/publish.js:157-168 (buildWikitext) — no changes needed for new builtin templates
Persistencesrc/api/user-store.js (Preferences.json) — read path needs the back-compat fallback

Acceptance criteria

  • Templates tab no longer offers Custom template.
  • Inline + Add custom wikitext-template column form is gone from the Columns tab.
  • Custom wikitext-template column entry is gone from the "+ Add column" popover.
  • All 8 templates above appear in the Templates tab, ordered by prevalence, as an expandable list (not cards).
  • Each expanded row shows wikitext preview, param→column mapping, and docs link.
  • Per-param required/optional badge + expected-value hint in the expanded row.
  • Existing user preferences with id: 'Custom' don't crash the app — fall back to Information.
  • npm run build passes (undefined-identifier scanner runs first).

Out of scope

  • Adding new workbench column types for template-only concepts (taxon, projection, composer, etc.). Those params stay unmapped; user fills them via free-text or a future MR.
  • Bulk migration of users' existing customProps of kind: 'template' (custom-wikitext columns). See Q-2.

Event Timeline

Daanvr moved this task from To do to Doing on the Tool-upload-workbench board.

Grooming pass (AI)

Voice-typed multi-part task. Investigated codebase + external Commons templates; rewriting the description (above) with concrete scope and proposing a sub-MR split. Original preserved here verbatim:

from what i have tested and seen there should not be a possibility to create custom wikitext-template. therefore the feature to add a column that way should be removed.

We already have the possiblity to select a different template.

How can we make sure to suport all the templates? please reasearch what templates exist. and add them all to be suported.
Fro each template research all the possible fealds that can be used in that template. these would all be possible to use as a column.

it is important to be extensive in this regard because there is no flexible way for the user to add custom columns or values.

There must be documentation on the available templates and their fields and maybe more information like expected values and value constraints. follow those as much as posssible.

some UI changes in the Column modal under the template tab the template are presented in cards. thisis unmpractival make it a list and when one is selected it extends to show wikitext, values, if they are visible as columns in the table and more information on this template with a link to the documentation. order the template by prevalence.

also remove the custom wikitext from the ad new column button at the end of the table.

Investigation findings

Codebase state (origin/main = v0.31.0):

  • 4 built-in templates today: {{Information}}, {{Artwork}}, {{Photograph}}, {{Book}} — defined in src/wikitext-templates.js:40-153 (BUILTIN_TEMPLATES). Each has a fields[] (param → workbench-column-key map), requiredColumns, recommendedColumns.
  • Custom template id (id: 'Custom') is added at use-time via resolveTemplate() (src/wikitext-templates.js:229-244) — supports a free-form body with {{field:KEY}} placeholders.
  • Templates tab UI: TemplatesPanel in src/columns-modal.jsx:447-667 — current layout is radio-card (tmpl-options flex row of TemplateOption cards, columns-modal.jsx:526-544). The Custom template card sits last.
  • Custom-wikitext-column creator (separate concept!): CustomColumnCreator in src/columns-modal.jsx:332-422 — the inline + Add custom wikitext-template column form at the bottom of the Columns tab.
  • "+ Add column" button: NOT in v0.31.0. Lives on branch feat/T426421-new-column-button (MR !49, currently in Reviewing — see T426421). AddColumnPopover in that branch's src/table.jsx:4730-4940 has a "Custom wikitext-template column" entry-point at table.jsx:4915. The task description's "just-shipped" wording is slightly off — !49 is still open. This task's "remove the custom wikitext from the +Add column button" is therefore a deletion *coordinated with* !49, not a hotfix to merged code.

External research — templates that exist on Commons:

From [[Commons:File description page]] and [[Commons:Infobox templates]], the file-description templates in active use are:

#TemplateUse-case
1{{Information}}Default — generic media (recommended for most user uploads)
2{{Artwork}}Paintings, sculptures, museum artifacts. {{Painting}} redirects here
3{{Photograph}}Photographs from museums/cultural institutions, with photographer + EXIF-friendly fields
4{{Art photo}}Photographs *of* artworks — separate photographer + artwork license
5{{Book}}Scanned books, manuscripts, multi-page works
6{{Map}}Maps — with projection / scale / coordinates
7{{Specimen}}Biological specimens (taxon, authority, accession)
8{{Musical work}}Audio files

Field inventories (from each template's documentation page):

  • {{Information}}: 7 params — description (req), date (sug, ISO 8601), source (req), author (req), permission (opt), other versions (opt), other fields (opt).
  • {{Artwork}}: ~30 params — artist, author, photographer, title, object type, description, depicted people, depicted place, depicted part, date, medium, dimensions, institution, department, accession number, place of creation, place of discovery, object history, exhibition history, credit line, inscriptions, notes, references, source (req), permission, other_versions, wikidata, wikidata_cat, strict, demo.
  • {{Photograph}}: ~22 params — photographer, title, description, depicted people, depicted place, date, medium, dimensions, institution, department, references, object history, exhibition history, credit line, inscriptions, notes, accession number, source, permission, other_versions, wikidata, original description, camera coord, strict, demo.
  • {{Art photo}}: ~25 params (two syntaxes: with/without Wikidata) — photographer, photo description, photo date, photo license, artwork license, source, plus full artwork sub-set.
  • {{Book}}: ~30 params — Author, Translator, Editor, Illustrator, Title, Subtitle, Series title, Volume, Edition, Publisher, Printer, Publication date, City, Language, Description, Source, Permission, Image, Image page, Pageoverview, Wikisource, Homecat, Other_versions, ISBN, LCCN, OCLC, Institution, Department, Accession number, References, Linkback, Wikidata, noimage.
  • {{Map}}: ~40 params — author (req), source (req), title, wikidata title, description, legend, date, permission, map date, location, wikidata location, type, projection, scale, zoom, heading, latitude, longitude, warp status, warp url, set, wikidata set, sheet, book author, book title, volume, page, language, publication place, publisher, printer, print date, ISBN, LCCN, OCLC, institution, accession number, dimensions, scan resolution, medium, credit line, inscriptions, notes, other versions, references, image.
  • {{Specimen}}: ~13 params — taxon (req), authority, institution, accession number, gender/sex, discovery place, cultivar, photographer/author, source, date, description, permission, other fields 3, other fields.
  • {{Musical work}}: ~16 params — composer, lyrics_writer, performer, title, description, composition_date, performance_date, notes, record_label, record_ID, image, references, source, permission, other_versions, other_fields.

Prevalence ordering (no clean Commons-API stat, going on documentation prominence + maintainer-canon order in current code): Information > Photograph > Artwork > Book > Map > Art photo > Specimen > Musical work.

Proposed sub-MR split

The task as written easily occupies 1500-3000 LOC + a non-trivial UI redesign. Splitting into incremental MRs lets us land value early and bail out early if any piece needs rethinking:

MR-1 — Remove + redesign (no new templates). Smallest useful first change.

  • Remove the Custom template option from the Templates tab (columns-modal.jsx:537-543 TemplateOption for Custom).
  • Remove the CustomColumnCreator (columns-modal.jsx:307-312, 332-422) — the inline "+ Add custom wikitext-template column" form at the bottom of Columns tab.
  • Remove the "Custom wikitext-template column" entry-point from AddColumnPopover in MR !49's branch — coordinate with the !49 author so it lands together. Cleanest sequence: merge MR-1 first → !49 rebases to drop that section, OR drop the entry from !49 directly before merging.
  • Templates tab redesign: cards → expandable list. Each row shows template name + one-line description; click to expand → wikitext-preview block + field table (param ↔ workbench column key + visibility checkmark) + docs link to https://commons.wikimedia.org/wiki/Template:<Name>. Order by prevalence (currently the Object.values(BUILTIN_TEMPLATES) order — make explicit).
  • Preserve back-compat for users with stored { id: 'Custom', body, fields } in their Preferences.json: silently fall back to Information (or to the closest builtin) on load. Don't crash on unknown id.
  • Migration concern: any user with stored custom-wikitext columns (customProps with kind: 'template') — these are saved as columns, not as a template. Decision needed: hide them but keep the data, or migrate them to something, or warn? (See Q-2 below.)

MR-2 — Add the missing templates. Add {{Map}}, {{Art photo}}, {{Specimen}}, {{Musical work}} to BUILTIN_TEMPLATES with full fields[] (param → workbench column key) and recommendedColumns. For each, decide which params map to existing workbench columns (e.g. descriptiondescription, datedateTaken, sourcesource) and which become unmapped (rendered empty unless filled by user). Where a template introduces a concept the workbench doesn't model (e.g. taxon, projection, composer), leave key: null — the wikitext won't carry the value but the user can still see the param exists in the expanded template view.

MR-3 — Field-level documentation + value constraints. Per-param tooltip / hint in the expanded row: required/optional badge, "expected value" hint (e.g. "ISO 8601 date"), per-param docs link (e.g. Template:Information#date). This is the "follow value constraints as much as possible" part — at minimum: surface required-vs-optional and the human-readable expected-value note from each docs page.

Out of scope (call out, don't ship): adding new workbench column types for template-only concepts (e.g. a taxon column, a projection column, a composer column). That's a meaningfully bigger refactor; the v1 of this task can leave those params unmapped and the user fills them via the expanded-view's free-text input (if we add one) or via a future MR.

Open questions for maintainer

See follow-up comment with the @Daanvr ping.

Daanvr moved this task from Doing to Needs input on the Tool-upload-workbench board.

@Daanvr — task is groomed (see comment + rewritten description above). Before I implement, three concrete scope decisions only you can make. The cost of guessing wrong on any of these is real refactoring afterwards, so I'd rather pause:

Q-1: Scope of the first MR. I see three reasonable splits — which do you want for v1?

  • Option A (smallest): MR-1 only — remove the custom-wikitext surface area + redesign Templates tab to expandable list, but don't add any new templates yet. Lands in a day. Lets you eyeball the new UI before I commit to the full template inventory.
  • Option B (medium): MR-1 + MR-2 — same as A, plus add Map / Art photo / Specimen / Musical work to BUILTIN_TEMPLATES. ~2-3x the diff size. Ships the user-facing "all templates supported" promise in one go.
  • Option C (full task): MR-1 + MR-2 + MR-3 — everything above, plus per-param required/optional badges + expected-value hints + per-param docs anchors. Full spec, biggest MR.

    My instinct: Option B, then a follow-up task for MR-3. Per-param hints feel like polish that's easier to iterate on once the structure is in place. But I'll do whichever you say.

Q-2: What happens to existing custom-wikitext columns and templates on user pages?

Some users may already have:
- `wikitextTemplate = { id: 'Custom', body: '...', fields: [...] }` saved in their `Preferences.json`.
- `customProps` of `kind: 'template'` (custom-wikitext **columns**) saved in their column list.

Three options:
- **(a) Silent fallback + drop:** custom template falls back to `Information`; custom-wikitext columns become hidden / removed silently. Cleanest code, riskiest UX (loses user data without warning).
- **(b) Silent fallback + preserve data:** custom template falls back to `Information` but the `body`/`fields` stay in the JSON for forensic recovery; custom-wikitext columns become read-only "Legacy" columns the user can manually delete from the Columns tab. Loudest visible footprint.
- **(c) Show one-time migration banner:** "These custom-wikitext columns were removed in v0.X.X — here's their content if you want to copy it elsewhere." Most polite UX, more code.

My instinct: **(a)** for a hackathon project at v0.31.0 — the install base is small, custom-wikitext usage is presumably ~zero. But you may have stronger feelings about not nuking user data silently.

Q-3: Coordination with MR !49 (T426421 "+ Add column").

!49 introduces the very `Custom wikitext-template column` entry-point that this task wants removed. Two ways to sequence:
- **(i) Land this task first** (in some form), then ask !49 author (also you) to rebase and drop those lines.
- **(ii) Ask the !49 author to amend !49 directly** to drop the Custom-wikitext entry before it lands, then this task only needs to remove the modal-side bits.

My instinct: **(ii)** — !49 hasn't merged yet, so the cleanest history is to drop those lines from !49 directly and skip the round-trip.

I'll wait per the back-off cadence. Will resume the moment the task moves out of Needs input or you reply.

Q1 is C
Q2 is A
Q3 !49 is already in main. correct the error made there in the mr

Daanvr renamed this task from no custom wikitext-template columns to no custom wikitext-template columns (!59).May 15 2026, 10:44 PM
Daanvr moved this task from Doing to Reviewing on the Tool-upload-workbench board.

please also remove the custom wikitext template column button form the add new column dropdown at the end of the table

Addressed feedback: the Custom wikitext-template column entry in the "+ Add column" popover was still in the committed code on this branch (the prior agent had it as unstaged work but never committed). New commit 5bee7da deletes it along with the onOpenCustomTemplateForm prop, the colMenuCustomFormOpen tri-state, and the initialCustomFormOpen prop on ColumnsModal that only the now-gone entry-point ever set.

npm run build is clean (undef scanner passes), pipeline #187644 succeeded, preview rebuilt:

Verified the built JS bundle no longer contains the "Custom wikitext-template column" string. The CHANGELOG entry — which already claimed this surface was removed — is now accurate.

Lessons learned

  • Pre-deciding ambiguous design questions before implementation accelerated this MR significantly. The maintainer's Q-1/Q-2/Q-3 answers on the task — Q-1 (full scope = removal + new templates + per-param docs), Q-2 (silent fallback for legacy id: 'Custom', no migration banner), Q-3 (fix the !49 entry point in this MR) — meant the implementer hit zero blocking decisions during the build-out. Tasks that have shape-affecting questions ("how should we handle X stored value?") benefit from this pattern: groom the task with explicit Q/A pairs at the top so the implementer knows the decisions are made and doesn't have to re-litigate them. Worth carrying forward to future scope-removal tasks that touch persisted user data.
  • Mid-flight scope collision with a peer MR (!49 / T426421) was caught early but only by accident. T426421 ("+ Add column" popover) landed *during* this MR's implementation cycle and added a fourth entry-point ("Custom wikitext-template column") to the very thing this MR was removing. The Q-3 pre-decision handled it cleanly (fix the entry-point in this MR) but only because the maintainer was reviewing both tasks concurrently and noticed the conflict. The systemic gotcha: in-flight MRs that touch the same UI surface can silently re-add what another MR is removing — and per-branch CI won't catch it. Mitigations going forward: when grooming a removal task, scan in-flight MRs (glab mr list) for the same surface area, and have the implementer skim those diffs as part of pre-work.
  • Cross-MR conflict surfaced only at merge time, but the local merge-result build caught it cleanly. This MR was rebased before !52 (T426422, per-language Caption columns) landed, so getAllColumns in src/table.jsx had two simultaneous mutations: HEAD's filter-out-kind:'template' (T426449) and origin/main's new captionExtras (T426422). Three-way merge produced a conflict marker. Resolution was straightforward (keep both: HEAD's filter and origin/main's captionExtras in the return) but it surfaced only during the merger's pre-merge local rebase + build — neither per-branch CI run could have caught it because each branch was syntactically valid in isolation. Re-confirms the existing CLAUDE.md rule that mergers must rebuild against the merge result locally; no new durable rule needed.