How to obtain a list of all macros in the current page?

I’m working on a Confluence plugin that allows users to embed some content into a page via a macro. There can be multiple macro instances in a single page and I would like to get a list of them all (including their parameter settings).

I found out that I can get the HTML code of the current page with getBodyAsString():

ContentEntityObject curPage = context.getPageContext().getEntity();;

And I could parse this code for the “imgId” that I’m interested in:

<ac:structured-macro ac:name="My Macro" ac:macro-id="be129df2-2e6b-4664-98f4-8613c1a4521c">
	<ac:parameter ac:name="imgId">EB5C24F1-54B6-4c7b-93FF-4B36FAA4212</ac:parameter>

But this seems too “fragile” and I feel like I would be reinventing the wheel. Is there maybe a Manager or Service that could easily return me a list of macros in a page object?


I now found that there is something called a MacroInstanceFinder. I can create one, but I have no clue how this could be used to get a list of all macros in a given page.

ContentMacroService.MacroInstanceFinder f = 

Does anyone know how to obtain a list of macros in a given page?

Hello hello !

You can use the XhtmlContent interface for this purpose , take a look at the handleMacroDefinitions method , see javadoc available here XhtmlContent (Atlassian Confluence 7.4.9 API)

You can use it in combination with the ContentService as follow to collect the macros that are parsed out of a content body.

From what I recall , MacroInstanceFinder was made to look up macros by ID/hash only (so it’s a single fetcher), and needs some extra love to add support for a fetchMany method which would return a collection of macros … (hint hint @ggautam might want to add that sometime soon ?)

    public Response getMacros(@PathParam("id") final long contentId) {
        final String contentBody = contentService.find(ExpansionsParser.parse("")).withId(ContentId.of(contentId)).fetch()
                .map(content -> content.getBody().get(ContentRepresentation.STORAGE).getValue())
                .orElseThrow(notFound("content not found for id: " + contentId));

        final Collection<Map<String, Object>> macroDefinitions = new ArrayList<>();
        try {
                    new DefaultConversionContext(new RenderContext()),
                    (macro) -> macroDefinitions.add(
                            ImmutableMap.<String, Object>builder()
                                    .put("name", macro.getName())
                                    .put("macroId", macro.getMacroIdentifier().orElse(MacroId.fromString("none")).getId())
                                    .put("parameters", macro.getParameters())
                                    .put("body.text", macro.getBodyText())
                                    .put("body.type", macro.getBodyType())
                                    .put("valid", macro.isValid())
                                    .put("schema.version", macro.getSchemaVersion())
            return Response.ok(macroDefinitions).build();
        } catch (XhtmlException exception) {
            return Response.serverError().entity(exception.getMessage()).build();

Code example available here

I hope this helps

Hasnae R.
(former Confluence person)