I looked at what extensions can do now that #maybeAddNode (XWiki.DocumentTreeMacros) maps node types to macros explicitly. Unknown node types are now silently ignored, so the custom nodes are returned by the Java tree but never rendered.
Options available to extensions right now (no change in platform)
Redefine #maybeAddNode in the extension, handling the custom types and delegating the rest to the core macros. This works, but:
the extension has to copy the core dispatch, which falls behind whenever the platform adds a node type;
Velocity registers macros when a template is parsed, so the redefinition must be in a velocity block that runs after {{include reference="XWiki.DocumentTreeMacros"/}}. If it's earlier, the include registers the core macro again over it;
it replaces the macro for the whole tree rendering (getChildren, getPath, suggestions);
it depends on a macro that was never meant to be API. So it's OK as a temporary workaround, but I wouldn't document it as the recommended way.
Redefining #addChildNodes / #getChildren / #getPath instead is worse: more copied code, same problems.
Proposals for the platform
Short term, can be backported: keep the explicit mapping for the core node types and add a fallback for the other types that calls #maybeAdd<Type>Node. It would apply only to node types made of letters and digits, since a macro name has to be an identifier anyway. Existing extensions, including the procedure flavor, would work again without changes.
Alternative without dynamic dispatch: the fallback calls a single #maybeAddCustomNode($nodeType $nodeReference $siblings $placeholder) macro, which does nothing by default and which extensions redefine. Extensions would need a small change, and the macro ordering caveat above still applies.
Long term (master), a real extension point: the tree structure is already extensible through TreeNode components (one per node type). What's missing is the node data (text, icon, URL, data attributes, whether it has children). We could add a component role, e.g. TreeNodeDataProvider (one per node type), in xwiki-platform-index-tree-api, exposed through $services.index.tree, and use it as the fallback in #maybeAddNode. Then custom node types wouldn't need any Velocity at all, and option 1 could be deprecated.
My preference: 1 (or 2) for the stable branches, and 3 on master. WDYT?
Marius Dumitru Florea on 20/Oct/26 09:26
I looked at what extensions can do now that {{#maybeAddNode}} (XWiki.DocumentTreeMacros) maps node types to macros explicitly. Unknown node types are now silently ignored, so the custom nodes are returned by the Java tree but never rendered.
*Options available to extensions right now (no change in platform)* * *Redefine {{#maybeAddNode}}* in the extension, handling the custom types and delegating the rest to the core macros. This works, but: ** the extension has to copy the core dispatch, which falls behind whenever the platform adds a node type; ** Velocity registers macros when a template is parsed, so the redefinition must be in a velocity block that runs *after* {{\{\{include reference="XWiki.DocumentTreeMacros"/\}\}}}. If it's earlier, the include registers the core macro again over it; ** it replaces the macro for the whole tree rendering ({{getChildren}}, {{getPath}}, suggestions); ** it depends on a macro that was never meant to be API. So it's OK as a temporary workaround, but I wouldn't document it as the recommended way. * Redefining {{#addChildNodes}} / {{#getChildren}} / {{#getPath}} instead is worse: more copied code, same problems.
*Proposals for the platform* # *Short term, can be backported:* keep the explicit mapping for the core node types and add a fallback for the other types that calls {{#maybeAdd<Type>Node}}. It would apply only to node types made of letters and digits, since a macro name has to be an identifier anyway. Existing extensions, including the procedure flavor, would work again without changes. # *Alternative without dynamic dispatch:* the fallback calls a single {{#maybeAddCustomNode($nodeType $nodeReference $siblings $placeholder)}} macro, which does nothing by default and which extensions redefine. Extensions would need a small change, and the macro ordering caveat above still applies. # *Long term (master), a real extension point:* the tree structure is already extensible through {{TreeNode}} components (one per node type). What's missing is the node data (text, icon, URL, data attributes, whether it has children). We could add a component role, e.g. {{TreeNodeDataProvider}} (one per node type), in xwiki-platform-index-tree-api, exposed through {{$services.index.tree}}, and use it as the fallback in {{#maybeAddNode}}. Then custom node types wouldn't need any Velocity at all, and option 1 could be deprecated.
My preference: 1 (or 2) for the stable branches, and 3 on master. WDYT?
Marius Dumitru Florea on 20/Oct/26 09:26
I looked at what extensions can do now that {{#maybeAddNode}} (XWiki.DocumentTreeMacros) maps node types to macros explicitly. Unknown node types are now silently ignored, so the custom nodes are returned by the Java tree but never rendered.
*Options available to extensions right now (no change in platform)* * *Redefine {{#maybeAddNode}}* in the extension, handling the custom types and delegating the rest to the core macros. This works, but: ** the extension has to copy the core dispatch, which falls behind whenever the platform adds a node type; ** Velocity registers macros when a template is parsed, so the redefinition must be in a velocity block that runs *after* the {{\include}} macro call that loads{\{include reference="XWiki.DocumentTreeMacros"/\}\}}}. If it's earlier, the include registers the core macro again over it; ** it replaces the macro for the whole tree rendering ({{getChildren}}, {{getPath}}, suggestions); ** it depends on a macro that was never meant to be API. So it's OK as a temporary workaround, but I wouldn't document it as the recommended way. * Redefining {{#addChildNodes}} / {{#getChildren}} / {{#getPath}} instead is worse: more copied code, same problems.
*Proposals for the platform* # *Short term, can be backported:* keep the explicit mapping for the core node types and add a fallback for the other types that calls {{#maybeAdd<Type>Node}}. It would apply only to node types made of letters and digits, since a macro name has to be an identifier anyway. Existing extensions, including the procedure flavor, would work again without changes. # *Alternative without dynamic dispatch:* the fallback calls a single {{#maybeAddCustomNode($nodeType $nodeReference $siblings $placeholder)}} macro, which does nothing by default and which extensions redefine. Extensions would need a small change, and the macro ordering caveat above still applies. # *Long term (master), a real extension point:* the tree structure is already extensible through {{TreeNode}} components (one per node type). What's missing is the node data (text, icon, URL, data attributes, whether it has children). We could add a component role, e.g. {{TreeNodeDataProvider}} (one per node type), in xwiki-platform-index-tree-api, exposed through {{$services.index.tree}}, and use it as the fallback in {{#maybeAddNode}}. Then custom node types wouldn't need any Velocity at all, and option 1 could be deprecated.
My preference: 1 (or 2) for the stable branches, and 3 on master. WDYT?
This message was sent by Atlassian Jira (v9.3.0#930000-sha1:287aeb6)
If image attachments aren't displayed, see this article.