Rate this page:

Dynamic Content Macro

A Confluence macro that loads remote content as an iframe. Dynamic Content Macros render content on every page request and are suitable for add-ons that need to display content that changes over time, that calls for dynamic interaction, or that is specific to the authenticated user.

Since Dynamic Content Macros are rendered in an iframe, you are able to include your own style sheets and javascript. You can use these to create a rich, interactive experience for your users. When your macro is exported to a static format such as PDF or Word, you can use the renderModes property to define a mapping between a certain type of output device and a static macro implementation. This will allow you to create a static view of your macro's data where an interactive model is not appropriate.

For most modules, you do not need to be concerned with iframe sizing. It's all handled for you. However, an exception exists for inline macros.

An inline macro is a type of macro that generates content within the text flow of a paragraph or other text element in which the macro appears, such as a status lozenge. To implement an inline macro, follow these general guidelines:

  1. In your macro-page declaration in the add-on descriptor, set the output-type attribute to inline. (Alternatively, if this value is set to block, the macro content will appear on a new line in the page output.)
  2. If the output content should occupy a certain width and height, set those values as the width and height attributes for the element.
  3. To prevent the macro output from being automatically resized, set the data-options attribute in the script tag for all.js to "resize:false". This turns off automatic resizing of the iframe.
  4. If the size of the macro output content size is dynamic, call AP.resize(w,h) immediately after the DOM of your iframe is loaded.

Example

The following macro example is an adaptation from the Google Maps add-on. The source is hosted on Bitbucket.

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
{
  "modules": {
    "dynamicContentMacros": [
      {
        "width": "200px",
        "height": "200px",
        "renderModes": {
          "pdf": {
            "url": "/render-map-pdf"
          },
          "default": {
            "url": "/render-map-static"
          }
        },
        "url": "/render-map?pageTitle={page.title}",
        "description": {
          "value": "Shows a configurable map"
        },
        "icon": {
          "width": 80,
          "height": 80,
          "url": "/maps/icon.png"
        },
        "documentation": {
          "url": "http://docs.example.com/addons/maps"
        },
        "categories": [
          "visuals"
        ],
        "outputType": "block",
        "bodyType": "none",
        "aliases": [
          "map"
        ],
        "featured": true,
        "parameters": [
          {
            "identifier": "view",
            "name": {
              "value": "Map View"
            },
            "description": {
              "value": "Allows switching between view types"
            },
            "type": "enum",
            "required": true,
            "multiple": false,
            "defaultValue": "Map",
            "values": [
              "Map",
              "Satellite"
            ],
            "hidden": false,
            "indexing": {
              "enabled": true
            }
          }
        ],
        "autoconvert": {
          "urlParameter": "url",
          "matchers": [
            {
              "pattern": "https://www.example.com/maps/{}/{}"
            },
            {
              "pattern": "https://www.example.com/map-editor/{}"
            }
          ]
        },
        "editor": {
          "url": "/map-editor",
          "editTitle": {
            "value": "Edit Map"
          },
          "insertTitle": {
            "value": "Insert Map"
          }
        },
        "name": {
          "value": "Maps"
        },
        "key": "dynamic-macro-example"
      }
    ]
  }
}

Properties

key
Type
Max length
100
Required
Yes
Pattern
^[a-zA-Z0-9-]+$
Description

A key to identify the macro. Keys must only contain alphanumeric characters and dashes, and must be globally unique. Prefixing it with the name of your add-on is the best way to ensure this.


name
Type
Required
Yes
Description

A human readable name.

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}

Properties

value
Type
Max length
1500
Required
Yes
Description

The human-readable default value. This will be used if no translation exists. Only the following HTML tags are supported: b, i, strong, em, and code.

i18n
Type
Max length
300
Description

The localization key for the human-readable value. Translations for the keys are defined at the top level of the add-on descriptor.


url
Type
Format
uri-template
Required
Yes
Description

The link to the add-on resource that provides the macro content. This URL has to be relative to the add-on base URL.

Additional context parameters can be passed as variables in the URL:

1
2
3
4
5

 {
   "url": "/macro-renderer?body={macro.body}&spaceid={space.id}&pageid={page.id}"
 }
 

Since macro bodies can be of arbitrary size and may contain sensitive data, care must be taken as to how its passed to your connect add-on. You have three options to gain access to the body:

  • If you can predict the size of your body and it is consistently less than 128 characters, you can include it in the GET request using the {macro.body} parameter.
  • If you know your macro contains a body that will often exceed the 128 character threshold (or is known to contain sensitive data), then you can include the {macro.id} parameter and use the Confluence REST api to call back to collect the body.
  • If you want, you can include, {macro.body}, {macro.id}, and {macro.truncated}. This way your plugin can call back to confluence only if {macro.truncated} is 'true'. This will allow you to skip the callback if it's not needed. This would be useful for macros that don't contain sensitive data of an unpredictable size.

Note: If you include the {macro.body} in your URL you are potentially leaking sensitive data to any intermediate host on the internet. This may result in the body being cached or indexed by a third party. If you are concerned about the security of your macro, you should always use the {macro.id} and use the Confluence REST API to collect the body.

Here's an example:

Declare the variables that are later required to fetch the macro content in the URL:

1
2
3
4
5

 {
   "url": "/render-macro?pageId={page.id}&pageVersion={page.version}&macroId={macro.id}"
 }
 

Then use the Confluence REST API to collect the body, for example directly from the iframe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

 AP.require("request", function(request) {
     var pageId = getUrlParameter("pageId");
     var pageVersion = getUrlParameter("pageVersion");
     var macroId = getUrlParameter("macroId");
     request({
         url: "/rest/api/content/" + pageId +
              "/history/" + pageVersion +
              "/macro/id/" + macroId,
         success: function(response) {
             var macro = JSON.parse(response);
             process(macro.body);
         }
     });
 });
 

Preview Mode: If you use the {macro.id} in your URL, the REST api will not return the macro body during a preview request, because the page has not been saved yet. You can use the {output.type} parameter to detect whether the macro is rendered in preview mode and adapt the response accordingly.

Note: macro.body will not be truncated when renderingMethod field was set to POST in static content macro. Refer to the Static Content Macros for information on how to set this field.

Currently supported variables for macros are:

  • macro.hash: The hash of the macro body (deprecated, use the macro.id)
  • macro.id: The id of the macro
  • macro.body: The macro body, truncated to 128 characters
  • macro.truncated: True if the macro body was truncated, false of not
  • page.id: The page ID, e.g. 1376295
  • page.title: The page title, e.g. My Page
  • page.type: The page type, e.g. page
  • page.version: The page version, e.g. 6
  • space.id: The space ID, e.g. 65537
  • space.key: The space key, e.g. AC
  • user.id: The user ID, e.g. admin (deprecated in GDPR mode)
  • user.key: The user key, e.g. ff80808143087d180143087d3a910004 (deprecated in GDPR mode)
  • output.type: The output type, e.g. display or preview

Context parameters for macros are also required in the URL. Please see the Macro Input Parameter documentation for details.


aliases
Type
Description

Define aliases for the macro. The macro browser will open for the defined aliases as if it were this macro.


autoconvert
Type
Description

URL patterns associated with this macro. If a URL matching a defined pattern is pasted into the editor, this macro will be created and will replace the URL string.

Autoconvert allows your macro to be inserted into the editor when a recognised URL is pasted in by the user. You define recognised URL patterns using 'matchers' which are registered in the editor when your add-on is installed.

When the macro is created in the editor, the URL string that triggered the autoconvert will be captured and inserted as a parameter on the macro body. You must define the name of this parameter by providing a string value for 'urlParameter'. This allows you to access the URL that triggered the autoconvert.

Example

This example inserts a macro into the editor when a user pastes in certain simple Facebook links.

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
34
35
36
37
38
39
{
  "renderModes": {},
  "url": "/dynamic-macro?url={url}",
  "categories": [],
  "outputType": "block",
  "bodyType": "none",
  "aliases": [],
  "parameters": [
    {
      "identifier": "url",
      "name": {
        "value": "URL"
      },
      "type": "string",
      "required": false,
      "multiple": false,
      "hidden": false
    }
  ],
  "autoconvert": {
    "urlParameter": "url",
    "matchers": [
      {
        "pattern": "https://www.facebook.com/{}/about"
      },
      {
        "pattern": "https://www.facebook.com/{}/music"
      },
      {
        "pattern": "https://www.facebook.com/{}/movies/{}"
      }
    ]
  },
  "name": {
    "value": "Dynamic Macro With Autoconvert"
  },
  "key": "dynamic-macro-with-autoconvert"
}

Properties

urlParameter
Type
Max length
100
Required
Yes
Description

The name of the macro parameter the matched url will be inserted into.

matchers
Type
Description

The list of patterns that define what URLs should be matched.


bodyType
Type
Defaults to
none
Allowed values
  • rich-text
  • RICH-TEXT
  • plain-text
  • PLAIN-TEXT
  • none
  • NONE
Description

The type of body content, if any, for this macro.


cacheable
Type
Defaults to
false
Description

Returns whether the URL should be cacheable. Cacheable URLs are taken directly from the add-on descriptor, and lack all additional query parameters:

  • standard iframe query parameters
  • product context parameters
  • JWT token


categories
Type
Description

The categories the macro should appear in. A macro with no category will show up in the default 'All' category.

Currently, the following categories are supported by Confluence:

  • admin: Administration
  • communication: Communication
  • confluence-content: Confluence Content
  • development: Development
  • external-content: External Content
  • formatting: Formatting
  • media: Media
  • navigation: Navigation
  • reporting: Reporting
  • visuals: Visuals & Images

description
Type
Description

A description of the macro's functionality.

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}

Properties

value
Type
Max length
1500
Required
Yes
Description

The human-readable default value. This will be used if no translation exists. Only the following HTML tags are supported: b, i, strong, em, and code.

i18n
Type
Max length
300
Description

The localization key for the human-readable value. Translations for the keys are defined at the top level of the add-on descriptor.


documentation
Type
Description

A link to the documentation for the macro.

Represents a link, its optional title and alternative text.

Example

1
2
3
4
5
6
7
8
{
  "link": {
    "url": "/go-somewhere",
    "title": "Go Somewhere",
    "altText": "somewhere"
  }
}

Properties

url
Type
Format
uri
Required
Yes
Description

The URL of the link. It can be absolute, or relative to the Add-On base URL.

altText
Type
Max length
1000
Description

Alternative text that is shown when the element cannot be rendered.

title
Type
Max length
1000
Description

The title of the link.


editor
Type
Description

The configuration of a custom macro editor. This is useful if the parameter input field types are not sufficient to configure the macro.

Macro Parameters go a long way when it comes to macro configuration, but there are cases when a macro add-on needs more control over the UI.

Defining a Macro Editor allows you to implement a custom UI for the macro, by specifying a URL to a page in your add-on which will be shown in the dialog iFrame.

In order to persist custom data in your macro editor, use the Javascript Confluence API and the Dialog API. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
AP.require(["confluence", "dialog"], function (confluence, dialog) {
    function onSubmit() {
        var macroParams = {
            myParameter: value
        };
        confluence.saveMacro(macroParams);
        confluence.closeMacroEditor();
        return true;
    }

    dialog.getButton("submit").bind(onSubmit);
});

In order to retrieve the custom data again when the editor is opened, use confluence.getMacroData (see Confluence API):

1
2
3
4
5
6
AP.require("confluence", function (confluence) {
    var macroData = confluence.getMacroData(function(macroParams) {
        doSomethingWith(macroParams.myParameter);
    });
});

Example

1
2
3
4
5
6
7
8
9
10
11
12
{
  "editor": {
    "url": "/map-editor",
    "editTitle": {
      "value": "Edit Map"
    },
    "insertTitle": {
      "value": "Insert Map"
    }
  }
}

Properties

url
Type
Format
uri-template
Required
Yes
Description

The URL to the macro configuration page in the add-on.

cacheable
Type
Defaults to
false
Description

Returns whether the URL should be cacheable. Cacheable URLs are taken directly from the add-on descriptor, and lack all additional query parameters:

  • standard iframe query parameters
  • product context parameters
  • JWT token

editTitle
Type
Description

An optional title that will be shown in the edit dialog header for an existing macro.

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}
height
Type
Max length
10
Description

The preferred height of the edit dialog, e.g. 300px.

insertTitle
Type
Description

An optional title that will be shown in the edit dialog header for a new macro.

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}
width
Type
Max length
10
Description

The preferred width of the edit dialog, e.g. 500px.


featured
Type
Defaults to
false
Description

Whether the macro should be "featured", meaning having an additional link in the "Insert More Content" menu in the editor toolbar.


height
Type
Max length
10
Description

The preferred height of the macro content, e.g. 10px,100%.


hidden
Type
Defaults to
false
Description

If set to true, the macro will not appear in the macro browser.


icon
Type
Description

A link to the icon resource (80x80 pixels) that will be shown in the macro selection dialog. The URL can be absolute or relative to the add-on base URL.

Defines an icon to display.

Example

1
2
3
4
5
6
7
8
{
  "icon": {
    "width": 16,
    "height": 16,
    "url": "/my-icon.png"
  }
}

Properties

url
Type
Format
uri
Required
Yes
Description

The URL of the icon. Your icon needs to be hosted remotely at a web-accessible location. You can specify the URL as an absolute URL or relative to the add-on's base URL.

height
Type
Description

The height in pixels of the icon image.

width
Type
Description

The width in pixels of the icon image.


imagePlaceholder
Type
Description

The image rendered in the editor as the macro placeholder. It can only be used with bodyless macros and will behave just like a regular macro placeholder. Any parameter changes in the macro browser will cause the image to be reloaded - so that changes can be seen.

Defines a macro image placeholder to display in the Confluence editor.

Example

1
2
3
4
5
6
7
8
9
{
  "imagePlaceholder": {
    "width": 100,
    "height": 25,
    "url": "/images/placeholder.png",
    "applyChrome": true
  }
}

Properties

url
Type
Format
uri
Required
Yes
Description

The URL of the image placeholder. Your image placeholder needs to be hosted remotely at a web-accessible location. You can specify the URL as an absolute URL or relative to the add-on's base URL.

The url here doesn't support context parameters. However all the macro parameters will be passed as query parameters to the request.
You can use these parameters to dynamically generate the placeholder image.

Suppose you have a macro defined like this:

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
34
35
36
37
38
39
40
41
{
  "dynamicContentMacros": {
    "renderModes": {},
    "url": "/my-macro",
    "categories": [],
    "outputType": "block",
    "bodyType": "none",
    "aliases": [],
    "parameters": [
      {
        "identifier": "param1",
        "name": {
          "value": "Parameter 1"
        },
        "type": "string",
        "required": false,
        "multiple": false,
        "hidden": false
      },
      {
        "identifier": "param2",
        "name": {
          "value": "Parameter 2"
        },
        "type": "string",
        "required": false,
        "multiple": false,
        "hidden": false
      }
    ],
    "imagePlaceholder": {
      "url": "/images/placeholder.png",
      "applyChrome": false
    },
    "name": {
      "value": "My macro with placeholder"
    },
    "key": "my-macro-key"
  }
}

The Confluence editor will pass the parameter values when requesting the placeholder image: /images/placeholder.png?param1=value1&param2=value2

applyChrome
Type
Defaults to
false
Description

Set to true if the image should have the macro placeholder chrome applied to it.

height
Type
Description

The height in pixels of the image placeholder. Defaults to the natural image height if not specified.

width
Type
Description

The width in pixels of the image placeholder. Defaults to the natural image width if not specified.


outputType
Type
Defaults to
block
Allowed values
  • block
  • BLOCK
  • inline
  • INLINE
Description

How this macro should be placed along side other page content.


parameters
Type
Description

The list of parameter input fields that will be displayed.


propertyPanel
Type
Description

The configuration of a property panel. Specify a hidden iframe to be loaded in the macro's property panel.

Defining a Macro Property panel allows you to add a hidden iframe to your macro's property panel. The iframe is loaded as soon as the property panel is opened.

In order to persist custom data using your property panel, use the Javascript Confluence API. For example:

1
2
3
4
5
6
7
AP.require(["confluence"], function (confluence) {
    var macroParams = {
        myParameter: value
    };
    confluence.saveMacro(macroParams);
});

In order to retrieve the custom data again when the property panel is opened, use confluence.getMacroData (see Confluence API):

1
2
3
4
5
6
AP.require("confluence", function (confluence) {
    var macroData = confluence.getMacroData(function(macroParams) {
        doSomethingWith(macroParams.myParameter);
    });
});

Dialogs may also be created. Use dialog.create (see Dialog API):

1
2
3
4
5
6
7
8
9
AP.require('dialog', function(dialog) {
    dialog.create({
        key: 'my-module-key',
        width: '500px',
        height: '200px',
        chrome: true
    }).on("close", callbackFunc);
});

Properties

url
Type
Format
uri-template
Required
Yes
Description

The URL of the add-on endpoint which will be served as a hidden iframe inside the property panel

cacheable
Type
Defaults to
false
Description

Returns whether the URL should be cacheable. Cacheable URLs are taken directly from the add-on descriptor, and lack all additional query parameters:

  • standard iframe query parameters
  • product context parameters
  • JWT token

controls
Type
Description

List of controls which will be added to the macro property panel


renderModes
Type
Description

Since Dynamic Content Macros are rendered in an iframe, you are able to include your own style sheets and javascript. When your macro is exported to a static format such as PDF or Word, you can use the renderModes property to define a mapping between a certain type of output device and a static macro implementation. This will allow you to create a static view of your macro's data where an interactive model is not appropriate.

Allows your dynamic content macro to provide different static macro implementations for different render modes.

Dynamic Content Macros can include style sheets and javascript, allowing the development of rich interactive applications. When your macro is rendered in a web browser this can provide a modern, interactive web experience.

When your macro is rendered to static formats such as PDF, or word, these interactive modes are often undesirable, or technically impossible.

Macro Render Modes allow you to map a render mode to a static content macro. This allows you to provide an implementation of your macro for these formats, that will render safely to static formats.

Example

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
{
  "modules": {
    "dynamicContentMacros": [
      {
        "renderModes": {
          "pdf": {
            "url": "/render-map-pdf"
          },
          "default": {
            "url": "/render-map-static"
          }
        },
        "url": "/render-map?pageTitle={page.title}",
        "categories": [],
        "outputType": "block",
        "bodyType": "none",
        "aliases": [],
        "name": {
          "value": "Maps"
        },
        "key": "dynamic-macro-example"
      }
    ]
  }
}

Properties

default
Type
Description

This render mode will be used for any static render mode that is not mapped directly. This is a catch all mode which allows you to set a default static fallback for all render modes.

1
2
3
4
5
6
{
  "default": {
    "url": "/render-map-default"
  }
}

An embedded reference to a static macro resource. These macro definitions are a subset of a Static Content Macro, defining only what cannot be inferred from the containing dynamic macro.

These embedded static content macros are used to define render mode mappings for your dynamic content macro.

Example

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
{
  "modules": {
    "dynamicContentMacros": [
      {
        "renderModes": {
          "pdf": {
            "url": "/render-map-pdf"
          },
          "default": {
            "url": "/render-map-static"
          }
        },
        "url": "/render-map?pageTitle={page.title}",
        "categories": [],
        "outputType": "block",
        "bodyType": "none",
        "aliases": [],
        "name": {
          "value": "Maps"
        },
        "key": "dynamic-macro-example"
      }
    ]
  }
}
email
Type
Description

This render mode will be used when your macro is being rendered during email rendering, and requesting the EXPORT_VIEW representation.

1
2
3
4
5
6
{
  "email": {
    "url": "/render-map-email"
  }
}

An embedded reference to a static macro resource. These macro definitions are a subset of a Static Content Macro, defining only what cannot be inferred from the containing dynamic macro.

These embedded static content macros are used to define render mode mappings for your dynamic content macro.

Example

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
{
  "modules": {
    "dynamicContentMacros": [
      {
        "renderModes": {
          "pdf": {
            "url": "/render-map-pdf"
          },
          "default": {
            "url": "/render-map-static"
          }
        },
        "url": "/render-map?pageTitle={page.title}",
        "categories": [],
        "outputType": "block",
        "bodyType": "none",
        "aliases": [],
        "name": {
          "value": "Maps"
        },
        "key": "dynamic-macro-example"
      }
    ]
  }
}
pdf
Type
Description

This render mode will be used when your macro is being rendered during "export to pdf".

1
2
3
4
5
6
{
  "pdf": {
    "url": "/render-map-pdf"
  }
}

An embedded reference to a static macro resource. These macro definitions are a subset of a Static Content Macro, defining only what cannot be inferred from the containing dynamic macro.

These embedded static content macros are used to define render mode mappings for your dynamic content macro.

Example

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
{
  "modules": {
    "dynamicContentMacros": [
      {
        "renderModes": {
          "pdf": {
            "url": "/render-map-pdf"
          },
          "default": {
            "url": "/render-map-static"
          }
        },
        "url": "/render-map?pageTitle={page.title}",
        "categories": [],
        "outputType": "block",
        "bodyType": "none",
        "aliases": [],
        "name": {
          "value": "Maps"
        },
        "key": "dynamic-macro-example"
      }
    ]
  }
}
word
Type
Description

This render mode will be used when your macro is being rendered during "export to word".

1
2
3
4
5
6
{
  "word": {
    "url": "/render-map-word"
  }
}

An embedded reference to a static macro resource. These macro definitions are a subset of a Static Content Macro, defining only what cannot be inferred from the containing dynamic macro.

These embedded static content macros are used to define render mode mappings for your dynamic content macro.

Example

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
{
  "modules": {
    "dynamicContentMacros": [
      {
        "renderModes": {
          "pdf": {
            "url": "/render-map-pdf"
          },
          "default": {
            "url": "/render-map-static"
          }
        },
        "url": "/render-map?pageTitle={page.title}",
        "categories": [],
        "outputType": "block",
        "bodyType": "none",
        "aliases": [],
        "name": {
          "value": "Maps"
        },
        "key": "dynamic-macro-example"
      }
    ]
  }
}

width
Type
Max length
10
Description

The preferred width of the macro content.


Rate this page: