Last updated Mar 27, 2024

How does RENDERMODE work?

StatusLEGACY. This tutorial applies to Confluence versions that have reached end of life.

Speaking generally, macros will want to do one of three things with their body:

  1. Pass the body through wiki -> html conversion, then do something to it like stick some more HTML around it. (i.e. {panel})
  2. Do something to the body, then pass it through wiki->html conversion (I don't really have an example of this)
  3. Treat the body as data, not as wiki text. (i.e. {tasklist})

getBodyRenderMode() makes the first case above really easy, because the macro renderer will convert your body from wiki text to HTML before it's passed to your macro's execute() method. That way your macro has ready-made HTML delivered to it, and you don't need to do anything.

If you return RenderMode.ALL from getBodyRenderMode(), then the body is rendered the same as a Confluence page. You can, however, return different values to only have a subset of renderings applied to your macro body: RenderMode.INLINE, for example, will ignore things like paragraphs, headers or blockquotes.

So, for example, the {color} macro returns RenderMode.INLINE, since you can only really use {color} inside a paragraph.

If you are doing macros of type 2 or 3, you'll need to return RenderMode.NO_RENDER, which means the raw body is passed into your macro with no pre-processing. You can then do whatever you want with it (including grabbing the SubRenderer component and converting it to wiki text yourself).

Here's the relevant portion of the MacroRendererComponent, which does all the work, if Java code is more your thing:

1
2
private void processMacro(String command, Macro macro, String body,
                          Map params, RenderContext context,
                          StringBuffer buffer)
 {
     String renderedBody = body;
     try
     {
         if (TextUtils.stringSet(body) && macro.getBodyRenderMode() != null
             && !macro.getBodyRenderMode().renderNothing())
         {
             renderedBody = subRenderer.render(body, context, macro.getBodyRenderMode());
         }

         String macroResult = macro.execute(params, renderedBody, context);

         if (macro.getBodyRenderMode() == null)
         {
             buffer.append(macroResult);
         }
         else if (macro.isInline())
         {
             buffer.append(context.getRenderedContentStore().addInline(macroResult));
         }
         else
         {
             buffer.append(context.addRenderedContent(macroResult));
         }

     }
     catch (MacroException e)
     {
         log.info("Error formatting macro: " + command + ": " + e, e);
         buffer.append(makeMacroError(context, command + ": " + e.getMessage(), body));
     }
     catch (Throwable t)
     {
         log.error("Unexpected error formatting macro: " + command, t);
         buffer.append(makeMacroError(context, "Error formatting macro: " + command + ": " + t.toString(), body));
     }
 }

Rate this page: