This tutorial primarily focuses on single-bodied macros, specifically those with either a "rich-text" or "plain-text" body type. For information and guidance on multi-bodied macros, please refer to our separate tutorial dedicated to that topic.
A macro body is content that the user can edit in your macro. Working with the macro body is useful if your macro is designed to format content. To get the macro body, your app needs to use macro variables in a REST API call.
By the end of this tutorial, you will:
dynamicContentMacros
module with a body type and URL parametersLet's get started!
Ensure you have installed all the tools you need for Confluence Connect app development by Getting set up with Atlassian Connect Express (ACE):
Before starting this tutorial, it is helpful to complete the previous tutorial: Creating a dynamic content macro.
Start by creating a fresh app to work with.
1 2atlas-connect new macro-body-tutorial
macro-body-tutorial
directory and run the following
command to install any dependencies for the app:
npm install
credentials.json
file that gives your app permission to work with your Confluence
Cloud development site. Copy the one you created during the
Getting started
tutorial. You can ignore or delete the existing credentials.json.sample
file.Add a dynamicContentMacros
object inside the modules
block of your app descriptor:
1 2"modules": { "dynamicContentMacros": [{ "url": "/myMacro?macroId={macro.id}&pageId={page.id}&pageVersion={page.version}", "description": { "value": "Allow users to add a background color around selected content." }, "bodyType": "rich-text", "name": { "value": "My macro" }, "key": "my-macro" }] }
Take note of the following fields:
url
: In addition to the endpoint, the URL includes parameters to capture the macro variables
macro.id
, page.id
, and page.version
, which are required for the REST API call to retrieve
the macro body.bodyType
: This is a required field for any macro that provides a body.For a list of macro variables, see Dynamic content macro.
Create a file called my-macro.hbs
in the views
directory:
1 2{{!< layout}} <div> {{#if body}} {{{body}}} {{else}} Here is a preview of your macro! {{/if}} </div>
This simple layout displays the macro body if it exists.
The route handler takes the variables passed in from the URL and uses them to make a REST API call to retrieve the macro body. For more information, see Get macro body by macro ID.
In routes/index.js
, add a new app.get()
method under the
// Add additional route handlers here…
comment:
1 2app.get('/myMacro', addon.authenticate(), function(req, res){ // Get the macro variables passed in via the URL const pageId = req.query['pageId'], pageVersion = req.query['pageVersion'], macroId = req.query['macroId']; // Get the clientKey and use it to create an HTTP client for the REST API call const clientKey = req.context.clientKey; const httpClient = addon.httpClient({ clientKey: clientKey }); // Call the REST API: Get macro body by macro ID httpClient.get( '/rest/api/content/' + pageId + '/history/' + pageVersion + '/macro/id/' + macroId, function(err, response, contents){ if(err || (response.statusCode < 200 || response.statusCode > 299)) { console.log(err); res.render('<strong>An error has occurred : '+ response.statusCode +'</strong>'); } contents = JSON.parse(contents); console.log(contents); // Render the view, passing in the {{{body}}} res.render('my-macro', { body: contents.body }); }); });
Notice how the macro variables are used to construct the REST API call. For an example of a slightly different way to make the call, see the Properties section of the Dynamic content macro reference page.
Now it's time to see the macro body in action:
macro-body-tutorial
directory and type npm start
to start
the app./my
and click My macro.When you load the page, you see the macro body, rendered as text on the page. On the command line,
you see the parsed contents of the macro, output by the statement console.log(contents);
in the
route handler. It should look something like this:
1 2{ name: 'my-macro', body: '<p>First test of my macro content!</p>', parameters: {}, _links: { base: 'https://<your dev instance>.atlassian.net/wiki', context: '/wiki' } }
You can also see the GET
call to your handler, including the populated variables:
1 2GET /myMacro?macroId=729c5f82-f62c-465b-b010-31777343d357&pageId=358416385&pageVersion=1&xdm_e=https%3A%2F%2Fyour%20dev%20instance.atlassian.net&xdm_c=channel-my-macro&cp=%2Fwiki&xdm_deprecated_addon_key_do_not_use=my-app&lic=none&cv=1.695.0 200 402.004 ms - 1391
Once you have access to contents.body
you can do more than just render it in a view: you can
change it, display it elsewhere, or use it like any other string.
If you decide to use a static content macro
instead of a dynamic content macro, you can
get the macro body the same way. The only difference is that you declare staticContentMacros
instead of dynamicContentMacros
in the app descriptor.
Rate this page: