Search code examples
javaconfluenceatlassian-plugin-sdk

How to render all of a page's children's content in a confluence macro


I am trying to build a simple confluence macro that renders all of the child pages of the current parent. Essentially a cross between the existing macros: children display, and include page. I did take a look at the source code for those macros, but since this is my first time developing in confluence, it was more confusing than helpful.

Right now I am working on the execute method, and since I am new to confluence development I am not sure 100% what exactly needs to go there.

I already read through Atlassian's Guide to Making a new Confluence Macro but it seems they just used html to wrap a list of properties of existing macros.

So I decided to look at the API, specifically Page I was able to get very close, the problem is, when I copy the page's bodies over I don't get the children's macros and styles that are in their pages.

    @Override
    public String execute(Map<String, String> parameters, String body,
            ConversionContext context) throws MacroExecutionException {
        //loop through each child page and get its content
        StringBuilder sb = new StringBuilder();
        ContentEntityObject ceo = context.getPageContext().getEntity();
        Page parent =(Page) ceo ;
        List<Page> children = parent.getChildren();

        for(Page child:children)

        {
          sb.append(child.getBodyAsString());
        }

        return sb.toString();
    }

How do I get all of it not just the text?

Also I am tagging this with java since that is what the plugins are written in.


Solution

  • There we go I figured it out.

    I needed to convert it from storage format to a view format for it to render the macros as well.

    {
    
      String converted = xhtmlUtils.convertStorageToView(child.getBodyAsString(), context);
      sb.append(converted);
    
    }
    

    xhtmlUtils was initialized in the constructor if you were following the tutorial

    private final XhtmlContent xhtmlUtils;
    
    public ExampleMacro(XhtmlContent xhtmlUtils) 
    {
        this.xhtmlUtils = xhtmlUtils;   
    }
    

    I also added annotations as per a suggestion at Atlassian answers

    @RequiresFormat(Format.Storage)
    public String execute(Map<String, String> params, String body, ConversionContext conversionContext) throws MacroExecutionException {
    

    where Format and RequiresFormat are these classes/annotations

    import com.atlassian.confluence.content.render.xhtml.macro.annotation.Format;
    import com.atlassian.confluence.content.render.xhtml.macro.annotation.RequiresFormat