I need to convert the content of a wiki page from its storage XWiki 2.1 syntax to the new UniAst syntax used by the BlockNote editor. I would like to perform this conversion from a Velocity script because the BlockNote integration relies on the Edit Module. Technically, I could do it from Java, but this means moving some HTML generating code from a template to Java. Moreover, I can’t rely on Document#getRenderedContent() API because the Edit Module decouples the edited content from the source document, and there’s no safe Document#getRenderedContent() signature to cover my case.
The rendering script service already has APIs to parse and render the content. It’s missing an API to execute the rendering transformations. Note that executing rendering transformations means executing script macros which is an important attack vector so it needs to be properly secured. The means using the right “transformation context”. In order to create this context we need to know:
the target syntax
whether to enable restricted mode or not
the lists of transformations
the context document (to evaluate script rights on)
In order to accept these parameters and possibly others in the future I suggest we use the builder pattern. The new API could be used like this:
That’s no fully accurate. The rights are evaluated on the content (secure) document, you just happen to also use it as context document by default.
+1 for the general idea, just need to refine a bit the naming (and there might be surprises requiring adding more stuff to the builder while implementing this)
While implementing this I realized that I need to introduce a new API to control the list of rendering transformations to execute per execution. We currently support customizing the list of transformations at the level of rendering configuration and at the level of HTTP request (through a request parameter). I think it makes sense to be able to set the list of transformations in the transformation context as well. This will lead to the following fallback chain:
adding TransformationContext#get/setTransformationNames; I propose we use the same naming as in the existing RenderingConfiguration#getTransformationNames()
modify DefaultTransformationManager to check the list from the transformation context first
the naming of $services.rendering.transform() is misleading because it doesn’t perform the transformation right away, but it rather creates the transformation context
we’re adding a new way / API to perform rendering transformations; there should be a single way ideally
the Velocity syntax I pasted above doesn’t work; we actually need to use something like:
we keep a single API to perform rendering transformations, which is TransformationManager
we make the platform implementation, XWikiTransformationManager, safer by using AuthorExecutor
but AuthorExecutor needs the content / source document reference, so we extend TransformationContext with XWikiTransformationContext, adding get/setContentDocumentReference
XWikiTransformationManager can then check if the passed TransformationContext can be cast to XWikiTransformationManager and use the AuthorExecutor in that case
if we need more information in the future (e.g. for security reasons) we can add that to the XWikiTransformationContext, and the script service doesn’t need any change.