Last modified by Vincent Massol on 2024/02/26 17:57



We have various macros which would need to cache intermediary result (script macros) or event the full result (code macro, message macros, etc.) of execution somewhere and while each macro could have its own caching system, dealing with invalidation can be tricky.

So one possibility to make all that a lot simpler would be to add a new step between the parsing and the execution of a XDOM. After you parse the source into a XDOM, you would go through a new API similar to transformations but dedicated to only do transformations which don't depend on the context so that you can cache the result of this "compilation" and reuse it every time you need to execute a XDOM. By doing that we delegate the cache storage and invalidation to a higher level which currently already does it for the parsed XDOM (the XWikiDocument stored in the document cache, the XDOM cached in the various wiki components like wiki macros, panels, ui extensions, generic wiki components, etc.).

How should a prepared XDOM looks like ?

It should stay as close as possible to the source XDOM to make easier to reuse existing tools (like the rendering transformation API). What should cover well the need is to simply add the concept of attributed to the MacroBlock (or even any Block ?).

How to prepare a XDOM ?

The simplest to add #prepare the Transformation.

So how exactly does a Macro component can prepare ?

A new void compile(MacroBlock block) would be added to org.xwiki.rendering.macro.Macro. The macro would preprocess everything it can preprocess without relying on variable contextual information and store whatever it wants as an attribute of the macro block.

When the Macro#execute is called the macro can reach the pre compiled data using MacroBlock#getAttribute() or do things from scratch if no data exists in the XDOM (not prepared XDOM).

Compiled data type

While the idea is to let each macro store any kind of compiled data (there is a huge difference between what the code macro and the velocity macro produce as compiled data and nothing in common) it's still nice to standardize which type of data a macro should produce in some common use cases:

  • a macro which content is just standard wiki content: the macro should compile it into a WikiContent which expose a getBlocks(). The reason to not return directly List<Blocks> is that the macro might also want to compile more things which it's putting around that content. Having this standard WikiContent can be very interesting for code which navigate a XDOM to find some elements like links (for example to find back links), if it's executed on a compiled XDOM it can very easily find a lot more elements which used to be blackboxed as String content of MacroBlock


Get Connected