Are there any plans (short- or long-term) for allowing Forge macros to be transformed to the view
or export_view
formats via the REST API (/rest/api/contentbody/convert
)?
Currently any Forge macros just render an error image in place for the macro because ac:adf-node
cannot be transformed (see steps to reproduce at the end).
It seems that Confluence has been going more and more towards rendering all content in the browser and not providing the same support via the REST API. That means that every app vendor that uses that API is not able to support Forge macros. For example we have multiple apps (at least 3 major ones) that would be affected by this.
Also the built-in PDF and Word exporters of Confluence also do not render these macros, which I assume is for the same reason.
I do understand that the current focus of Forge in terms of macros is the more interactive macros that would not work in a static export format anyway, but there will be macros that output content that could be rendered in a static way as well (images, tables, text). For these the best solution I could think of would be to give the macro developers a way to specify additional render functions that do not output UIkit components but some other static format like ADF. This would be similar to the renderModes
property in connect dynamic content macros .
Steps to reproduce:
Manually:
- Install a Forge app that has a macro module, for example the QR code example app
- Create a new page and insert the macro in it
- Export the page with either the Confluence PDF/Word Exporter or with Scroll PDF/Word Exporter
Shortcut:
Use this curl script that calls the REST API with a storage format snippet for a Forge macro (replace url with any available Confluence Cloud instance). Probably doesn’t matter if the macro that is referenced in the storage format there is installed or not, since it fails on an earlier ADF node anyway.
curl --request POST \
--url 'https://your-confluence-instance.atlassian.net/wiki/rest/api/contentbody/convert/export_view' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"value": "<ac:adf-extension><ac:adf-node type=\"extension\"><ac:adf-attribute key=\"extension-type\">com.atlassian.ecosystem</ac:adf-attribute><ac:adf-attribute key=\"extension-key\">4e13a71e-7712-433f-bd6b-7a13115bc02f/7e12ea90-1d3e-42e8-992d-b8619bd1f07b/static/qr-code</ac:adf-attribute><ac:adf-attribute key=\"parameters\"><ac:adf-parameter key=\"local-id\">1168ff01-b19c-4d67-bfa2-508774ed704b</ac:adf-parameter><ac:adf-parameter key=\"extension-id\">ari:cloud:ecosystem::extension/4e13a71e-7712-433f-bd6b-7a13115bc02f/7e12ea90-1d3e-42e8-992d-b8619bd1f07b/static/qr-code</ac:adf-parameter><ac:adf-parameter key=\"extension-title\">QR Code</ac:adf-parameter><ac:adf-parameter key=\"config\"><ac:adf-parameter key=\"color\">172B4D</ac:adf-parameter><ac:adf-parameter key=\"url\">https://www.placekitten.com/800/800</ac:adf-parameter></ac:adf-parameter></ac:adf-attribute><ac:adf-attribute key=\"text\">QR Code</ac:adf-attribute><ac:adf-attribute key=\"layout\">wide</ac:adf-attribute></ac:adf-node><ac:adf-fallback><ac:adf-node type=\"extension\"><ac:adf-attribute key=\"extension-type\">com.atlassian.ecosystem</ac:adf-attribute><ac:adf-attribute key=\"extension-key\">4e13a71e-7712-433f-bd6b-7a13115bc02f/7e12ea90-1d3e-42e8-992d-b8619bd1f07b/static/qr-code</ac:adf-attribute><ac:adf-attribute key=\"parameters\"><ac:adf-parameter key=\"local-id\">1168ff01-b19c-4d67-bfa2-508774ed704b</ac:adf-parameter><ac:adf-parameter key=\"extension-id\">ari:cloud:ecosystem::extension/4e13a71e-7712-433f-bd6b-7a13115bc02f/7e12ea90-1d3e-42e8-992d-b8619bd1f07b/static/qr-code</ac:adf-parameter><ac:adf-parameter key=\"extension-title\">QR Code</ac:adf-parameter><ac:adf-parameter key=\"config\"><ac:adf-parameter key=\"color\">172B4D</ac:adf-parameter><ac:adf-parameter key=\"url\">https://www.placekitten.com/800/800</ac:adf-parameter></ac:adf-parameter></ac:adf-attribute><ac:adf-attribute key=\"text\">QR Code</ac:adf-attribute><ac:adf-attribute key=\"layout\">wide</ac:adf-attribute></ac:adf-node></ac:adf-fallback></ac:adf-extension>",
"representation": "storage"
}'
Output:
{
"value": "<img src=\"https://your-confluence-instance.atlassian.net/wiki/plugins/servlet/confluence/placeholder/error?i18nKey=editor.placeholder.error&locale=en_GB&version=2\" title=\"Unhandled adf-node when trying to transform from storage to view format. Node is ac:adf-node\" class=\"transform-error\" data-encoded-xml=\"%3Cac%3Aadf-extension%3E%3Cac%3Aadf-node+type%3D%22extension%22%3E%3Cac%3Aadf-attribute+key%3D%22extension-type%22%3Ecom.atlassian.ecosystem%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22extension-key%22%3E4e13a71e-7712-433f-bd6b-7a13115bc02f%2F7e12ea90-1d3e-42e8-992d-b8619bd1f07b%2Fstatic%2Fqr-code%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22parameters%22%3E%3Cac%3Aadf-parameter+key%3D%22local-id%22%3E1168ff01-b19c-4d67-bfa2-508774ed704b%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22extension-id%22%3Eari%3Acloud%3Aecosystem%3A%3Aextension%2F4e13a71e-7712-433f-bd6b-7a13115bc02f%2F7e12ea90-1d3e-42e8-992d-b8619bd1f07b%2Fstatic%2Fqr-code%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22extension-title%22%3EQR+Code%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22config%22%3E%3Cac%3Aadf-parameter+key%3D%22color%22%3E172B4D%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22url%22%3Ehttps%3A%2F%2Fwww.placekitten.com%2F800%2F800%3C%2Fac%3Aadf-parameter%3E%3C%2Fac%3Aadf-parameter%3E%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22text%22%3EQR+Code%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22layout%22%3Ewide%3C%2Fac%3Aadf-attribute%3E%3C%2Fac%3Aadf-node%3E%3Cac%3Aadf-fallback%3E%3Cac%3Aadf-node+type%3D%22extension%22%3E%3Cac%3Aadf-attribute+key%3D%22extension-type%22%3Ecom.atlassian.ecosystem%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22extension-key%22%3E4e13a71e-7712-433f-bd6b-7a13115bc02f%2F7e12ea90-1d3e-42e8-992d-b8619bd1f07b%2Fstatic%2Fqr-code%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22parameters%22%3E%3Cac%3Aadf-parameter+key%3D%22local-id%22%3E1168ff01-b19c-4d67-bfa2-508774ed704b%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22extension-id%22%3Eari%3Acloud%3Aecosystem%3A%3Aextension%2F4e13a71e-7712-433f-bd6b-7a13115bc02f%2F7e12ea90-1d3e-42e8-992d-b8619bd1f07b%2Fstatic%2Fqr-code%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22extension-title%22%3EQR+Code%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22config%22%3E%3Cac%3Aadf-parameter+key%3D%22color%22%3E172B4D%3C%2Fac%3Aadf-parameter%3E%3Cac%3Aadf-parameter+key%3D%22url%22%3Ehttps%3A%2F%2Fwww.placekitten.com%2F800%2F800%3C%2Fac%3Aadf-parameter%3E%3C%2Fac%3Aadf-parameter%3E%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22text%22%3EQR+Code%3C%2Fac%3Aadf-attribute%3E%3Cac%3Aadf-attribute+key%3D%22layout%22%3Ewide%3C%2Fac%3Aadf-attribute%3E%3C%2Fac%3Aadf-node%3E%3C%2Fac%3Aadf-fallback%3E%3C%2Fac%3Aadf-extension%3E\" />",
"representation": "export_view",
"_expandable": {
"webresource": "",
"embeddedContent": "",
"mediaToken": ""
},
"_links": {
"base": "https://your-confluence-instance.atlassian.net/wiki",
"context": "/wiki"
}
}