Confluence Meta-Macros and the joy of being organized

Let’s talk about meta-macros.  That is, macros that examine other macros.   I just made up the term, so don’t be concerned if you can’t find other examples on the internet.

If you wanted some insight into which pages in your Confluence Instance were using a specific macro, how would you find that information?

You could certainly check each page manually, but that sounds dreadful.

One option to get Macro information is this ScriptRunner script that I wrote, which examines the latest version of each page in each Space for references to the specified macro:

 import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.pages.Page
def pageManager = ComponentLocator.getComponent(PageManager)
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def spaces = spaceManager.getAllSpaces()
  
def macroRef = 'ac:name="info"'
  
spaces.each {
  spaceObj ->
    def pages = pageManager.getPages(spaceObj, false)
  pages.each {
    page ->
      if (page.getBodyContent().properties.toString().contains(macroRef) && page.version == page.latestVersion.version) {
        log.warn("'${page.title}' (version ${page.version}) is the latest version of the page, and contains the target macro")
      }
  }
}
 

 

But what if you wanted MORE information?  What if you wanted to know every macro running on every page in the system, and you didn’t have ScriptRunner to do it for you?  In that

Introduction

Well, it finally happened.  I finally had to start learning JavaScript.

It’s actually not that bad, I probably should have learned a while ago.  My use case for it is writing Confluence Macros and plugins for both Confluence and Jira. I started with the plugins, for simplicity’s sake.  
My inspiration came from a post on the Atlassian Community Forums. Someone had requested a way to essentially mirror the setup of a macro. But they wanted to mirror the most recent child page, of a parent page.
I think that without pretty strong knowledge of Confluence and the REST API, I’d have struggled to complete this.  It enough work to learn JavaScript’s basic tenets as I went.

 

Digging Into The Problem

Okay so what do we actually need the script to do? We need it to:

  •  Figure out the most recently updated child page of a parent page
  •  Fetch the macro setup of the child page
  • Update the parent page accordingly

These are the three high-level functions that the macro needs to accomplish. 

Figuring out the most recently updated child page wasn’t hard.  You can make a call to baseURL + pageID + “/child/page?limit=1000&expand=history.lastUpdated. This returns a list