Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Next challenges

Recent achievements

  • Global
  • Personal

Recognition

  • Give kudos
  • Received
  • Given

Leaderboard

  • Global

Trophy case

Kudos (beta program)

Kudos logo

You've been invited into the Kudos (beta program) private group. Chat with others in the program, or give feedback to Atlassian.

View group

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Can I create macros within an HTML macro?

Hi,

I am just a user, and not an admin of my team's Confluence server. However, I frequently use the HTML macro to include snippets of Javascript to generate dynamic content of some sort. What I'd really like to do is to include an excerpt-include macro within that dynamic content. So, my javascript would generate/edit some html that could include 1 to several excerpt include macros based on some criteria.

Is this possible with Confluence?

Thanks

1 answer

Hi Willy,

It's a bit hackish, but not impossible:

<script>
function renderAndInsertMarkup(markup, containingElement) {
var dataObj = {};
dataObj.representation = "storage";
dataObj.content = {};
dataObj.content.id = AJS.params.pageId;
dataObj.value = markup;

jQuery.ajax({dataType: 'json',
contentType: 'application/json',
type: 'POST',
url: contextPath + '/rest/api/contentbody/convert/view',
data: JSON.stringify(dataObj),
success: function(response) {
jQuery(containingElement).append(response.value);
}
});
}
renderAndInsertMarkup(`<ac:structured-macro ac:name="cheese" />`, "#output-markup");
</script>
<div id="output-markup"></div>

This works perfectly. Thank you!

Thanks! This solution is what I'm looking for!

Hello,
@Stephen Deutsch could you explain the code in more detail?

I'm trying to do the same with the Popular Labels Macro what works basically. I'm trying to refine by means of its parameters but no clue how to get them into the code. 
Could you explain the purposes of the \ and / ?  I tried several approached inspired by using macros inside user macrosPossible to Call User Macro inside another User Macro?using macros inside user macros and Using confluence macro code inside user macro (entity names were exchanged) but nothing worked out. Could you help out?

it took me a while but I figured it out based on the description of Section Macro

\"your string\" is to mark a string including the quotation marks

var arg1 = "<ac:structured-macro ac:name=\"popular-labels\" > "+ 
				"<ac:parameter ac:name=\"style\">heatmap</ac:parameter> "+
				"<ac:parameter ac:name=\"spaceKey\">MANMECOSWIKI</ac:parameter> "+
			"</ac:structured-macro>"
renderAndInsertMarkup(arg1 , "#output-markup");

 

I still need some help here as I try the same with Contet By Label Macro, what was my original intention.  

By using the in browsers dev tools I figure out the macro name, what is contentbylabel. I did the same to give me an idea about the right parameters to be used in the code. 
The inspector gives me

data-macro-parameters="cql=label \= "amb" and label \= "glossary" and label \= "glossary_b"

but I how to work with the quotation marks around the label name in the code?
I tried without success:

  • <ac:parameter ac:name=\"cql=label\\">amb</ac:parameter> "
  • <ac:parameter ac:name=\"cql=label\\">"amb"</ac:parameter> "
  • <ac:parameter ac:name=\"cql=label\\">\"amb\"</ac:parameter> "
  • <ac:parameter ac:name=\"cql=label\\">\""amb"\"</ac:parameter> "
  • <ac:parameter ac:name=\"cql=label\\">&quot;glossary&quot</ac:parameter> "
  • <ac:parameter ac:name=\"cql=label\\">\"&quot;glossary&quot\"</ac:parameter> "

get macro name.png

Hi Stefan, sorry for not getting back to you sooner.

Instead of trying to figure out how to do the quotes, it might just be easier to use backticks: `` which are now supported by most modern browsers. Then just put the code inside and it should work OK.

Hoi Stephen,
no worries, I was on vacation anyway :).

May I try to understand your code. You can divide it roughly into four sections.
I try to explain where I can find documentation but that is not given for each line.

  1. creating a JavaScript Object
     var dataObj = {};
    Details e.g. on JavaScript Objects | w3schools. or How To Use Object Methods in JavaScript | DigitalOcean or a more complex application Passing Data as JS Objects | Chart Data | ZingChart
     dataObj.representation = "storage";
    I find only ContentRepresentation (Atlassian Confluence 5.8.8 API) but it is not self-explaining. I found some in Custom Content | developer.atlassian.com and How do you post markdown using confluences rest API? is enlighten me slightly but I'm still a bit clueless. 
     dataObj.content = {};
    dataObj.content.id = AJS.params.pageId;
    dataObj.value = markup;
    cannot find anything explaining their necessity. 

  2. erform an asynchronous HTTP (Ajax) request.

    jQuery.ajax({

    Details e.g. on jQuery ajax() Method | w3schoolsjQuery.ajax() | jQuery API Documentation.

      contentType: 'application/json',
    type: 'POST',
    url: contextPath + '/rest/api/contentbody/convert/view',
    data: JSON.stringify(dataObj),

     

    Can be properly explained well based on jQuery Ajax Post Method | freeCodeCamp Guide and javascript - Returning the response from an Jquery AJAX call - Stack Overflow.

    Confluence Server is asked to process the contentType: 'application/json', what comes as JSON string due to data: JSON.stringify(dataObj) by the API contentbody/convert/view, accessible via
    context path is the path to Confluence
    and the 
    Contentbody API (REST API examplesConfluence REST API Documentation)
    supported by 
    1. Dynamic Content Macro: How to retrieve rendered macro body | The Atlassian Developer Community 
    2. How do the various Confluence document formats differ? - Stack Overflow
    3. Confluence Rest API Maintaining Macros After View | The Atlassian Community.

  3. The append() method inserts specified content at the end of the selected elements.
    This happens when action two is successful

    jQuery(containingElement).append
    Due to the location in the HTML Macro,  the new Macro is added at the same spot where the HTML Macro is located and the pageID as part of the JS Object (see 1).
    More details about append are e.g. on
    1. jQuery append() Method | w3schools
    2. jquery .html() vs .append() - Stack Overflow
    3. append() | jQuery API Documentation

  4. The function call

    renderAndInsertMarkup(
    Based on the wording I assume that uses Confluence Wiki Markup and Confluence Storage Format, respectively, what renders the code but where is this documented?
    Could it be that all that we do here is to edit the underlying markup of a Confluence page, what is XHTML-based format that Confluence uses to store the content of pages, page templates, blueprints, blog posts and comments?

    I do not find anything in regard to structured macro. I find them only in the description of some macros as e.g. the Section Macro and View storage format | The Atlassian Community but in none of them is anything mentioned in regard of the quotation marks, where and how to use them.



@Stephen Deutsch, any chance that you may enlight me?

 

Stefan

@Stephen Deutschbefore we may get lost in details could you answer point 4 first?

Hi Stefan,

ac:structured-macro simply refers to a standard macro that is inserted on a page. If you insert any of the macros that are available to you, and then you click on "View Storage Format", then you should be able to see what the code looks like.

renderAndInsertMarkup takes Confluence Storage Format text and converts it to HTML. This is what Confluence does internally, but once the page has been rendered, the only way to convert is to use a REST API call. This is done using jQuery.ajax. You see that there is a div with an id of "output-markup" which is passed to the function as a parameter as well. This is where the HTML is output.

The most important thing to understand is the Confluence Storage Format in the request. You can't look at the HTML in the page to figure out the storage format. You have to choose the menu option "View Storage Format" to be able to figure out what you need. Looking at your original request, I tried to make an example that fulfills your requirements, copied directly from a page where I inserted a contentbylabel macro that looks for the labels amb, glossary, and glossary_b:

<script>
function renderAndInsertMarkup(markup, containingElement) {
var dataObj = {};
dataObj.representation = "storage";
dataObj.content = {};
dataObj.content.id = AJS.params.pageId;
dataObj.value = markup;

jQuery.ajax({dataType: 'json',
contentType: 'application/json',
type: 'POST',
url: contextPath + '/rest/api/contentbody/convert/view',
data: JSON.stringify(dataObj),
success: function(response) {
jQuery(containingElement).append(response.value);
}
});
}
renderAndInsertMarkup(`<ac:structured-macro ac:name="contentbylabel"><ac:parameter ac:name="cql">label in ( &quot;amb&quot; , &quot;glossary&quot; , &quot;glossary_b&quot; )</ac:parameter></ac:structured-macro>`, "#output-markup");
</script>
<div id="output-markup"></div>
Like # people like this

Thank you for all those information and code, I will try as soon as I have access to our confluence instance and a quiet moment.

What do mean by "View Storage Format" , do you refer to the source editor as mentioned here.

Hi Stefan, the "View Storage Format" menu option is available under the three dots menu (•••) when viewing a page. Otherwise you can use the Confluence Source Editor available on the marketplace. Both will show the underlying code of the page, but the source editor allows you to make changes, too.

nothing like this in my menu, only "View Source" comes close
page view - three dot menu.png

@Stephen Deutsch 

Is there any special considerations when using this in conjunction with the Jira macro? I can get a list to display if the original Jira macro is still on the page. If I remove this to leave the code to do it's thing then it no longer loads the list.

Jira Refreshing.png

The jira macro needs to perform it's own rest queries once inserted into the page. Hence you need to use a different endpoint for it:


url: contextPath + '/rest/api/contentbody/convert/export_view'

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Posted in Confluence Cloud

Please tell us how you use Confluence space settings

👋 Hi there, a few of us at Atlassian would love to learn about how you use "space settings" functionality in Confluence. A facelift to the space settings is long overdue and we want to start with im...

118 views 5 6
Join discussion

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