Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
Community Members
Community Events
Community Groups

Adding nested macros to confluence page via API (ScriptRunner)


Hi community,

Just posting a question here since I've been having trouble finding resources for this.

While using scriptrunner to create a page, I can add macros to it. I do it through XML like this:

xml.'ac:structured-macro'('ac:name':"section) {
'ac:rich-text-body'("here are some values to be shown in the body of the macro")
but keep running into problems when I try to add a macro within the body of that first macro. Can someone tell me what I'm missing here or point me at some documentation? Not sure how to bypass the 'WYSIWYG' editor many of these macro's have. Here is an example of one attempt of mine:
xml.'ac:structured-macro'('ac:name':"section") {
'ac:inline'('ac:structured-macro'('ac:name':"column") {
'ac:rich-text-body'("there should be some value in here")
EDIT: Found during testing and looking at other documentation pages that you can specify 'inline' instead of 'rich-text-body' or 'plain-text' and it will read a little bit of the code. It was just reading the string value "there should be some value in here" instead of just "ac:structured-macro". Still not invoking the macro to be nested in the section macro.

1 answer

Posting the solution here. Bear in mind I'm working with groovy in the scriptrunner console in Jira, and not a python file to run on the backend with a curl request:

-Create the page
-Retrieve the page body in storage format. It will be in an XHTML document object.
-Make necessary alterations to the document object
-execute PUT request - see below

Resources that were very helpful!
Document (jsoup Java HTML Parser 1.15.2-SNAPSHOT API) also see 'Element'
And many more forum posts that may not have been directly helpful but gave me a better idea of what I was looking for


def params = [

    type : "page",

    title: pageTitle, // <------- grab the original page title if not changing or specify a new one

    version: [

        number: "2" // <----- I hard incremented during testing. Grab the original page version and + 1 it


    status: "current", // <------------ you can make it a draft if you so please

    body : [

        storage: [

            value         : new_bod, //<-------- literally just take the modified xhtml document and .toString() it

            representation: "storage"



All for this:

I was a bit frustrated you can't just create both the macros at the same time, although now I may try just formatting the page in XHTML in the first place instead of going through an xml writer in the script to create a page initially. If I succeed I will post more info here.

Suggest an answer

Log in or Sign up to answer
Community showcase
Published in Confluence

An update on Confluence Cloud customer feedback – June 2022

Hi everyone, We’re always looking at how to improve Confluence and customer feedback plays an important role in making sure we're investing in the areas that will bring the most value to the most c...

154 views 1 3
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you