Last updatedMay 5, 2020

Rate this page:

Working with custom content children

DescriptionSetup and create instances of a new Note content type, contained within 'Customers'.
Level

Intermediate

Estimated time20 minutes
Examplehttps://bitbucket.org/atlassianlabs/confluence_cloud_tutorials/src/custom-content/

Prerequisites

Ensure you have worked through Searching custom content.

Another custom content type

We will now declare another custom content type in our descriptor, just like we did with customers. Let's call them 'notes'.

atlassian-connect.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
"customContent": [
  // Add this under the "Customer" type
  {
    "key": "note",
    "name": {
      "value": "Notes"
    },
    "uiSupport": {
      "contentViewComponent": {
        "moduleKey": "customersViewer"
      },
      "listViewComponent": {
        "moduleKey": "notesViewer"
        },
      "icons": {
        "item": {
          "url": "/images/notes.png"
        }
      }
    },
    "apiSupport": {
      "supportedContainerTypes": [
        "ac:my-app:customer"
      ]
    }
  }
]

We also add more information to our customer custom content type, as follows:

atlassian-connect.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"customContent": [
  {
    "key": "customer",
    //  More options above here...
    "apiSupport": {
      "supportedContainerTypes": [
        "space"
      ],
      "supportedChildTypes" : [
        "ac:my-app:note"
      ]
    }   
  }
]

We have introduced a new key here, namely, supportedChildTypes. This establishes a heirarchy where a 'Note' can be contained within a 'Customer', and that a 'Note' is a supported child type of a 'Customer'.

Just like in Working with custom content, we will create a note from a dialog box. Let's add another dialog module to our descriptor.

atlassian-connect.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"dialogs": [
  // Add this under the new customer dialog
  {
    "key": "newNote",
    "url": "/add-new-note?spaceKey={space.key}&contentId={content.id}",
    "options": {
      "height": "420px",
      "width": "600px",
      "header": {
          "value": "Add a new note"
      }
    }
  }
]

Here, we see space key and content ID as the URL parameters. These are just a few of the context variables that Confluence supports. We need these to make an API request to create notes.

Once we have added the above, we need to create a route for /add-new-note to render the dialog box.

routes/index.js

1
2
3
4
5
6
7
8
app.get('/add-new-note', addon.authenticate(), function (req, res) {
    var contentId = req.query['contentId'];
    var spaceKey = req.query['spaceKey']
    res.render('new-note',{
        contentId: contentId,
        spaceKey: spaceKey 
    });
});

In terms of understanding the backend code needed, we are all done! Let's quickly look at how to create a note and retrieve all notes under a customer.

Noteworthy content

Using AP.request, we perform the following:

views/new-note.hbs 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{{!< layout}}

var jsonData = {
  "type": "ac:my-app:note",
  "space": {
    "key": "{{spaceKey}}"
  },
  "container": {
    "type": "ac:my-app:customer",
    "id": "{{contentId}}"
  },
  "title": "Hello, World",
  "body": {
    "storage": {
      "value": "Goodbye, boy",
      "representation": "storage"
    }
  }
};

AP.request({
  url: '/rest/api/content',
  type: 'POST',
  contentType: 'application/json',
  data: JSON.stringify(jsonData),
  success: function(note){
    note = JSON.parse(note);
    console.log("Note successfully persisted to Confluence", note);
  },
  error: function(err){
    console.log(err);
  }
});

Let's pretend our customer has an id of 156831. To see our note as a child of our customer, we issue a GET request to the /rest/api/content/156831/child/ac:my-app:note endpoint. We should receive a response like this: 

1
2
3
4
5
6
7
8
9
10
{
  "results": [
    {
      "id": "1605728",
      "title": "Hello, World",
      // More properties...
    }
  ],
  // More below here...
}

And, voila! A connection has been established between the customer, and the note underneath them. As you can see, this affords great possibilities to app developers in the Confluence Ecosystem. Custom content well and truly provides a fully-integrated content solution.

To wrap up, we now have all the essentials we need to build the UI we want in Confluence! Here's another snapshot of what 'notes' could look like in Confluence:

essentials to build the UI you want in Confluence

This concludes our deep-dive into the capabilities of Custom content in Confluence Connect.

Happy dev-ing!

Rate this page: