Doc brainstorming: Consistency of the macro parameter table

Hello!

Context

While progressing on the WYSIWYG usability of XWiki macros proposal, I noticed that our documentation of macro parameters is very inconsistent. Unfortunately, for some macros, this documentation still plays a huge role for new users to understand what the macro actually does.

I listed the macro documentation URLs, kept the 55 distinct pages hosted on extensions.xwiki.org, and parsed every parameter table they render. I am sharing what I found (with Claude Code to help with the research and the counting) and the direction I am leaning towards, because I might miss something and would like to improve the state of this documentation.

Observations

37 of the 55 pages carry a parameter table, for 43 tables in total. 18 pages carry none.

Those 43 tables use 14 different column signatures:

Columns Tables
Name / Optional / Allowed values / Default value / Description 27
Parameter name / Default value / Description 2
Name / Description / Mandatory / Default 2
Name / Description / Default Value / Since 2
10 other shapes 1 each

One major inconsistency is that the same concept is spelled Optional, Mandatory and Mandatory? depending on the page, so a reader who skims sees yes in that column and cannot tell whether the parameter is required without going back up to the header. This small fact alone is already one way the documentation inconsistency makes it less usable.

The section heading above the table has 9 spellings (Parameters definition 20, Parameters 10, Parameter definition 4, Parameter definitions 3, Usage 2, plus a few one-offs). That is also why cross-links have to point at #HUsage for some macros and #HDescription for others.

The cell values diverge just as much. Over the 98 rows of the dominant 5-column shape:

  • Optional: yes (78), no (15), but also no or reference, no or page and yes (default: 'user'), which put a condition into a column that reads as binary.
  • Allowed values: empty in 19 rows. a string (8) and string (8) are the same thing. Booleans are spelled true/false (9), true or false (2), boolean (1) and boolean (true/false) (1). References are A page reference, Document reference, A document reference and document.
  • Default value: empty in 25 rows, then five spellings of “nothing”: none (16), N/A (7), - (2), The empty string (2), empty string (1).
  • Name: always plain text, never code formatted, so nothing tells the reader that parameter ids are case sensitive.

And on the 18 pages with no table, the fallbacks are all different: “No parameters.” (Comment macro), “See the Script Macro for details.” with no section of their own (Python and Groovy macros), a bullet list under Usage (Context macro), or simply nothing at all (Live Data, Icon, JIRA, and the Info/Success/Warning/Error macros).

Improvements

Nothing below is settled, this is just what I plan to do in the future in regards to what we observed.

Implement a single canonical table, with a fixed heading and five columns always present in this order (even if a column might not look necessary for a macro):

== Parameters ==

|=Name|=Mandatory|=Type|=Default value|=Description
|##title##|no|string|##none##|The title displayed in the box.
|##status##|no|boolean|##false##|XWiki 17.1+ Marks the message as a status message so assistive technology announces it.

Three naming calls are where community validation would be the most valuable:

  • Mandatory rather than Optional. It costs a rename on 27 tables, but it is the word ParameterDescriptor#isMandatory uses and the word the CKEditor macro editor dialog shows to the user, so the documentation would stop being the only place using the inverted polarity. Quite a lot of changes but also quite a benefit.
  • Type rather than Allowed values. That column currently does two jobs, giving a type (a string) on some rows and an enumeration (line, area, bar, pie, ...) on others. An enumeration is arguably just the type of an enum parameter, but maybe some of you see those as genuinely different things.
  • Parameters rather than Parameters definition. It is the minority spelling today (10 against 20), so this one is mostly about getting a shorter heading and a single stable #HParameters anchor.

In addition to those wording choices, we probably also want:

  • A controlled vocabulary per column, so that two macros cannot say the same thing differently: the parameter id is code formatted, Mandatory is strictly yes or no with conditional cases explained in the description instead, the Type is picked from a small closed list (string, boolean, integer, page reference, attachment reference, syntax id, list of strings, or enum followed by the allowed values), and a Default value that is either a literal in ##code##, the bare word none, or ##""## when the default really is the empty string, but never blank and never N/A.
  • A few optional columns, always after Description and always in the same order: Advanced, Since, Deprecated. Those columns are only included if they make sense to add for at least one parameter.
  • Content treated as a parameter. For content-centered macros, as opposed to info retrieval ones, the content is the main point of the macro and most parameters are secondary, yet the content appears in none of the 43 tables. I would give every macro that accepts content a first row named ##content##, with the same cells as any other parameter. Even if technically the content parameter holds a special place, for users it looks just like another parameter.
  • All macros in XS should have a page with their Parameters section, so that “does this macro take parameters?” always has an answer. If there are no parameters, the section would say so explicitly rather than being absent, and a macro reusing another macro’s parameters would still have the section, with a link to the macro it reuses rather than no section at all.

How to avoid regression

Agreeing on the table above is one thing, keeping 55 pages aligned on it over time is another. A contract that lives only in the documentation guide is a contract we have to re-check at every review, and the numbers above show how that ends.

In my opinion the best way to handle it is a simple wiki macro bundling a velocimacro that is fed the parameter data by hand and only takes care of validating and rendering it.

{{macroParameters}}
{{macroParameter name="title" type="string"}}The title displayed in the box.{{/macroParameter}}
{{macroParameter name="status" type="boolean" default="false" since="17.1.0"}}Marks the message as a status message so assistive technology announces it.{{/macroParameter}}
{{macroParameter name="classname" type="page reference" mandatory="yes"}}The class of the object holding the attachment.{{/macroParameter}}
{{/macroParameters}}

A lot of consistency choices are decided once in its definition, and cannot drift page by page: the column set and their order, the heading, the code formatting of the ids, none versus ##""##, which optional columns appear and where, and what gets rendered when the list is empty.

Open questions

  • Does the canonical table above look right to you, or would you shape the columns differently?
  • Does treating content as a parameter row make sense, or would you rather document it separately?

I am going to start moving in this direction, any feedback is welcome at any point, and the earlier the better :slight_smile:

Thank you!
Lucas C.

@CharpentierLucas I have not read your proposal yet but I wanted to ask you if you had checked the agreed proposal at [XWiki Docs Reorg - Batch 17]: Template for Documenting Rendering Macros first?

Thx

I forgot about it, checking it out, thanks!