Hello everyone. I am trying to understand the following scenario in our XWiki 17.6.0 environment.
Please note that I simplified the macro implementation to a minimal working sample.
Macros
I have a simple “Content Block” Macro that displays some content with summary and details:
Content Block Macro
{{velocity}}
#set ($openAttribute = "open")
#if ($wikimacro.parameters.isOpen == false)
#set ($openAttribute = "")
#end
{{html wiki="true"}}
<details class="panel panel-default" $openAttribute>
<summary>
<span class="panel-title">
Click to expand...
</span>
</summary>
<div class="panel-body">
{{wikimacrocontent/}}
</div>
</details>
{{/html}}
{{/velocity}}
I also have an “Include Content Block” Macro that is used to extract the content of a content block from a target page and outputs a new content block with that content on another page. A context macro is used to simulate the context of the source page to allow local references to work. It is similar to the ExperctIncludeMacro.java:
Include Content Block Macro
@Component
@Named("include-content-block")
public class IncludeContentBlockMacro extends AbstractMacro<IncludeContentBlockMacroParameters>
{
@Inject
private Provider<XWikiContext> xWikiContextProvider;
@Inject
private Provider<ComponentManager> componentManagerProvider;
public IncludeContentBlockMacro()
{
super("include-content-block", "include-content-block", IncludeContentBlockMacroParameters.class);
setDefaultCategories(Set.of(DEFAULT_CATEGORY_CONTENT));
}
@Override
public List<Block> execute(IncludeContentBlockMacroParameters parameters, String content, MacroTransformationContext context)
{
try
{
XWikiContext xContext = xWikiContextProvider.get();
DocumentReference sourceDocumentReference = parameters.getSourcePage();
XWikiDocument sourceDocument = xContext.getWiki().getDocument(sourceDocumentReference, xContext);
//Find the first matching content block in the source page
List<MacroBlock> macroBlocks = sourceDocument.getXDOM().getBlocks(new ClassBlockMatcher(MacroBlock.class), Block.Axes.CHILD);
MacroBlock matchingBlock = null;
for (MacroBlock macroBlock : macroBlocks)
if (macroBlock.getId().equals("my-content-block")) matchingBlock = macroBlock;
if (matchingBlock == null)
return List.of(new MacroBlock("warning", new HashMap<>(), "content block not found", false));
//Get the content from the content block
ComponentManager cm = componentManagerProvider.get();
Parser macroContentParser = cm.getInstance(Parser.class, sourceDocument.getSyntax().toIdString());
XDOM sourceContentBlockContent = macroContentParser.parse(new StringReader(matchingBlock.getContent()));
XWikiDocument tempDocument = new XWikiDocument(null);
tempDocument.setContent(sourceContentBlockContent);
//Create a new content block and put the content from the source block inside
MacroBlock inhaltsblockMacro = new MacroBlock("my-content-block", Collections.emptyMap(), tempDocument.getContent(), false);
BlockRenderer blockRenderer = cm.getInstance(BlockRenderer.class, sourceDocument.getSyntax().toIdString());
WikiPrinter contentBlockPrinter = new DefaultWikiPrinter();
blockRenderer.render(inhaltsblockMacro, contentBlockPrinter);
//Wrap the new content block in context macro to simulate context from source page
Map<String, String> contextMacroParameters = new HashMap<>();
contextMacroParameters.put("document", sourceDocumentReference.toString());
contextMacroParameters.put("transformationContent", "document");
MacroBlock contextMacro = new MacroBlock("context", contextMacroParameters, contentBlockPrinter.toString(), false);
return Collections.singletonList(contextMacro);
}
catch (Exception e)
{
return List.of(new MacroBlock("error", new HashMap<>(), "error", false));
}
}
@Override
public boolean supportsInlineMode()
{
return false;
}
}
Usage
I have a source document with the following content:
{{my-content-block isOpen="false"}}
{{info}}Hello World{{/info}}
{{/my-content-block}}
I know that a standalone macro should be wrapped with empty lines in XWiki 2.0+ syntax.
But lets assume this is how the content would be migrated from confluence. The info box is displayed as a standalone macro:
I have another document with the following content:
{{include-content-block sourcePage="TestSourcePage.WebHome"/}}
Here I want to display my content block from the source page. It works, but the content inside of the content block is displayed in an inline context, so the info box is displayed differently:

I spend a lot of time in the debugger in the xwiki-rendering project trying to understand why the content is transformed in an inline context when the “Include” macro is used. I tried to track down the whole process but even tho the code is actually pretty well written (thank you btw
) it is still rather complex. I guess for some reason the {{wikimacrocontent/}} inside the included (newly created) content block is treated in a different transformation context.
Do you have any idea what might cause this or could you point me in the right direction?
