XObjects display macro
- XWiki
- Design
- Active
- No
Description
Abstract
A macro that displays a Live Data table whose rows are the pages holding an object of a chosen XClass, and whose columns are a free mix of doc.* metadata and that class's properties. It is configurable entirely from the WYSIWYG macro dialog, so an author who does not write XWiki syntax can build a sortable, filterable report over structured data.

What every option renders: a sortable, filterable table over the pages holding the chosen class. The rendering layer is identical in all four options below; only the authoring experience differs. (R4)
Motivation
Currently, it is difficult for non-technical users to add listings of their structured data from the editor.
Creating a structure is decently easy with App Withing Minute (AWM).
But, from there, adding a list of the data added from in an AWM, with custom filtering and sorting, is not easy achievable.
Users can use the Live Data macro, but list generic nature (e.g., supports several sources) makes it hard to use.
This is especially important in the context of users familiar with Confluence or Notion, where such listing are easily done.
Use cases
- UC1: A non-technical user (e.g., a project manager) can insert a listing of XObject from an XClass they created (e.g., using AWM).
- UC2: An author who does not know XWiki syntax configures that table entirely from the WYSIWYG macro dialog.
- UC3: A reader of the page filters and sorts the table themselves, without editing anything.
- UC4: An author restricts the table to one sub-page, and chooses whether nested pages are displayed too.
UC5: An author wants a plain list of pages with no data type at all. Equivalent to the {{documents}} macro. Already covered by the documents macro- UC6: An author reopens the macro months later to add a column, and finds their existing configuration rather than defaults.
UC7: (optional, probably best covered by a contrib extension) A Confluence migration turns a Page Properties Report into this macro, with the migrator creating the class.- UC8: A property is renamed or removed from the class after the macro was configured, and the page still renders.
- UC9: A reader without permission on some of the matching pages sees a table containing only what they may see.
- UC10: A reader with edit rights is able to add entries to the table, and edit existing entries, in-place, if the author allowed it.
Specification
- R1: Rows are documents holding an object of a chosen XClass; columns are a free mix of doc.* metadata and that class's properties. (UC1)
- R2: The macro is fully configurable from the WYSIWYG dialog; no parameter requires handwritten syntax. (UC2)
- R3: Each column is sortable and filterable where the underlying property allows it, with the filter widget derived from the XClass property type. (UC3)
- R4: Live Data is the rendering and interaction layer, i.e., no table re-implementation. (UC3, UC10)
- R5: Column order is authored and preserved as authored. (UC1)
R6: (optional) Omitting class reproduces the current {{documents}} macro behavior. (UC5)- R7: The configuration round-trips: the dialog reopens on the saved state, and reopening then saving without edits changes nothing. (UC6)
- R8: The row set can be restricted by location, with an explicit choice about nested pages. (UC4)
- R13: It is possible to see the impact of a change of macro property while editing the macro.
- R14: It is possible for readers to add entries and to edit existing entries if their rights allow it. (UC10)
Macro ID: records
Macro name: Records
Macro descriptor:
| Parameter | Type | Mandatory | Advanced | Default | Group | Description |
|---|---|---|---|---|---|---|
| class | String (XClass reference) | Yes | No | (none) | Data | The type of data the listed pages hold. (R1) |
| properties | String (comma-separated) | No | No | all, class order | Data | The columns to fetch and display, in the order given. Class properties and doc.* metadata. (R1, R5) |
| location | String (reference) | No | No | current wiki | Scope | Restrict the listed pages to this space or page. (R8) |
| nested | Boolean | No | No | true | Scope | Include pages nested under the location. (R8) |
| editable | Boolean | No | No | false | Editing | Let readers add and edit entries directly in the table, where their rights allow it. (R14) |
| layouts | String (comma-separated) | No | No | table | Display | The layouts the reader can choose from. The first is loaded initially. |
| description | String | No | No | (none) | Display | Textual description of the table, announced to assistive technology. (R12) |
| sort | String (comma-separated) | No | Yes | first column | Display | The columns the table is sorted on initially. Each name may be suffixed :asc or :desc. |
| filters | String (query string) | No | Yes | (none) | Display | Filters applied before the reader sees the table. |
| limit | Integer | No | Yes | 15 | Display | Rows shown per page. (R11) |
| translationPrefix | String | No | Yes | (none) | Display | Translation key prefix for column headers instead of raw property names. |
| id | String | No | Yes | generated | (none) | Identifier for this table, required only when a page holds more than one. |
class is the only mandatory parameter. The macro editor should therefore block insertion until a class is chosen, which is what makes the properties widget meaningful when it is first displayed.
Parameter dependencies
Static structure: Which parameters belong together, or are alternative ways of expressing one thing. Known statically (@PropertyGroup and @PropertyFeature).
Value dependency: the valid options for one parameter depend on the runtime value of another. No annotation in the Properties Module expresses this; it has to be implemented in a custom displayer declared with @PropertyDisplayType.
| Dependent | Depends on | Kind | What the macro editor must do |
|---|---|---|---|
| properties | class value | Value | Repopulate the column list from that class's properties plus doc.* metadata |
| filters | class value | Value | Derive each filter widget from its property's type (R3) |
| sort | properties value | Value | Offer only the columns actually fetched |
| nested | location being set | Presence | Disable the control when the location is the whole wiki |
| limit | Live Data pageSizes | Consistency | Keep the default page size within the offered page sizes |
The load-bearing one is class -> properties. Every other row is cosmetic or can be worked around by hand; that one is what R2 ("no parameter requires handwritten syntax") and UC2 promise. It needs a custom @PropertyDisplayType displayer and a macro editor that re-renders a parameter widget when a sibling parameter changes. Whether the editor supports that is an open question, not an implementation detail.
Mapping to livedata
- The liveTable source should be enough
Rationale and rejected ideas
- The document macro is focused on listing pages and must stays specialized for this specific task. The macro define in this page specializes in displaying structured entries. The fact that xobjects are stored in pages is an implementation detail.
- A new macro is required to make it fine-tuned for usability for non-technical users
- Listing structured data is a core part of XWiki and while the implementation stays modular, it makes sense to have it part of xwiki-platform and available by default.
Options
Each option below is mocked in the two states created by the class -> properties dependency: before a data type is chosen, and after.
Option 1 - No improvements

Option 1, before a class is chosen. class is a free-text reference, so the author has to already know it.

Option 1, with a class typed in. The reference is only validated after the fact, and properties remains a comma-separated string the author fills from memory — nothing repopulates from the class.
This is basically a rewrite of the Live Data (LD) macro, but with a fine-tuned vocabulary, plus a removal of all the generic aspects of LD (e.g., no source choice).
No custom displayers, no conditional display of parameters.
Option 1.1: No parameter validation, everything is passed to the LD, LD error messages are presented to the user
Option 1.2: Server side parameters validation
Pros:
- Cheapest
Cons:
- Poor usability
Option 2.1 - With custom displayers

Option 2.1, before a data type is chosen. An XClass picker searches the available applications, the dependent parameters stay disabled, and insertion is blocked until a type is picked. (R2, UC2)

Option 2.1, with a data type chosen. The column chooser lists that class's own properties alongside doc.* metadata, each with its type, and columns can be reordered by dragging. (R3, R5, R7)
Some parameters are based on custom displayer. For instance, a XClass picker is used for the XClass selection, instead of asking for a string.
Parameters that depend on each other are hidden or disabled until the required value is set. For instance, the sort is displayed until the XClass is selected.
Pros:
- Improve usability
Cons:
- Higher development and maintenance costs
Option 2.2 - With custom displayers and custom preview

Option 2.2, as 2.1 plus a preview of the table inside the dialog, so the author sees the effect of each parameter change while editing. (R13)

The same dialog with nine columns kept. The preview pane is narrower than the page the table will land on, so it scrolls horizontally where the real page will not.
Same are 2.1, but a preview of the LD that will be displayed once the macro is insert is presented directly in the macro form.
Pro:
- Quick usability win
Cons:
- The notion of macro preview is already something we want to work on, and introducing an adhoc implementation for this macro is wasteful unless we absolutely don't want to wait
Option 3 - In-place edition

Option 3, just after insertion. The macro asks for its data type in place, in the editor, with no dialog.

Option 3, configured in place. The table's own toolbar and header drive the parameters, each interaction writing one back and refreshing the render.
Instead of displaying the usual macro modal, the macro has no parameters editable in the modal. Instead, the LD is tweaked to offer interactions that results in a change in parameters internally (and a refresh of the display), directly from the editor.
Pro:
- Seamless integration, zero back and forth to a macro dialog to tweak the display; closted to what Notion proposes
Cons:
- Experimental, likely the more expensive option
- Probably also harder to generalize, meaning more custom development for each macro that would match this look & feel.
I would only pick this option is we consider xobjects listing an absolutely primordial feature that deserves a special treatment.
Considerations
| Characteristic | Assessment |
|---|---|
| Accessibility | R12: The table's description is announced to assistive technology, and keyboard navigation is not worse than a bare Live Data. |
| Usability | TODO |
| Internationalisation | TODO |
| Backwards compatibility | TODO |
| Security | R10: View rights are enforced on rows and reflected in the result count. |
| Performance | R11: The rendered table is paginated and must not scan the full result set to display its first page. |
| Reliability | R9: A missing class or property degrades to a legible message, never a stack trace, and never silently drops the whole table. |
| Maintainability | TODO |
| Sustainability | TODO |
| Documentation | TODO |
Open questions
N/A
Prior art and references
- The existing {{documents}} macro; the closest thing in XS today, and per R6 a subset of this proposal.
- Live Data; the rendering layer this builds on, per R4.
- Confluence's Page Properties Report macro; the equivalent feature users migrate from, per UC7.