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

HTML Macro: manipulate another macro's result

Can I use the HTML macro to manipulate the outcome of another macro such as the Page Tree Macro?

1 answer

1 accepted

Yes, as you can execute arbitrary JavaScript you can manipulate anything in the DOM. However it's not very advisable to vastly change HTML that other JavaScript might rely on. In the case of a Page Tree Macro it should be okay but generally you can always break functionality by manipulating HTML that is "not yours" (rendered/created by you).

That it good news but that get me to question how to do it ☺️.

I want to to filter the page tree. I want only shown what are labeled by certain label.

How can I loop through the result of the Page Tree Macro, check the page's label(s) and hide them if they don't match?

I'll try to give you a short JS lesson here but you'll quickly figure that this is not a beginner friendly problem and that doing it via JS is not the best solution in this case.

First you'll want to look at the HTML that is generated by the macro.

pagetreemacrohtml.PNG

As you can see it is a UL with the class plugin_pagetree_children_list. Each direct child LI represents a top level item in the page tree. Using the selector .plugin_pagetree_children_list > li we can grab all of those:

var listItems = $('.plugin_pagetree_children_list > li');

Once we got the LIs we need to look at the HTML again to find the node that contains the text.

pagetreemacrohtml2.PNG

As you can see these nodes have the class .plugin_pagetree_children_content and we only want the :first one because we are in a tree and there might be children. Once we have the text we can perform a check against it to see if we should remove the item.

function yourFilter(text) {
return true; // perform your own check here
}

$('.plugin_pagetree_children_list > li').each(function(index, item) {
var $item = $(item);
var text = $item.find('.plugin_pagetree_children_content:first').text().trim();

if (yourFilter(text)) {
$item.remove();
}
});

Of course you will need to put your own logic into yourFilter(). As you said want to check the labels of these pages you will need to perform a REST call here to get the labels for each page. This is very inefficient and also problematic because you only have the page title at this point but not the page id.

Now we need to do the same thing again for all list items in the child tree of our list item (if there is one). Oh, and then we also need to check if we removed all children of an item because if there are no children anymore we need to alter the HTML so the node is not expandable anymore.

pagetreemacrohtml3.PNG

And this of course needs to be done for all child items as well...

I'm gonna stop here. As you see you got yourself in for a ride and this problem is not as simple as you might've thought. Especially if you're new to JavaScript.

I'd strongly suggest writing your own Page Tree Macro instead of doing this via JS. That should be a whole lot simpler and much more stable and performant.

wow, that is more than I could expect!

lugin_pagetree_children_list > li

why do you include '> li'?

we can grab all of those

what happens if the macro is used multiple times on the page. I reckon the filter function has to deal with it, isn't it?

we only want the first one because we are in a tree

only first you say, as there could be child pages, isnt' it?

And this of course needs to be done for all child items as well...

laborious but feasible :) 

I'm gonna stop here. As you see you got yourself in for a ride and this problem is not as simple as you might've thought. Especially if you're new to JavaScript

I'm not very new to JS but having problems understanding how to interact with Atlassian content

To be honest my suggestion would be to go another route and write your own special Page Tree Macro if you have these requirements

I would like but how to allow such user-driven development is still in discussion at IT (at a lower priority)

I could create a script and put it on a public repository. It could be called inside HTML Macro to create a customized page tree, but that would get me to the question how to loop through the child pages of a Space.
May Writing User Macro to list children of page limited by label - Where can I find Confluence Methods? tells how to do it but I wondering how to get this in an HTML Macro to work?

why do you include '> li'?

Because we want the listitems (li) and not the ul. But there's 100 different ways to do this.

what happens if the macro is used multiple times on the page. I reckon the filter function has to deal with it, isn't it?

I haven't handled this case. Another reason why you should just build your own macro instead.

only first you say, as there could be child pages, isnt' it?

Yes.

I could create a script and put it on a public repository. It could be called inside HTML Macro to create a customized page tree, but that would get me to the question how to loop through the child pages of a Space.

If you're doing this via JS your only choice is to use the Confluence REST API. Depending on the amount of pages in your tree this might require hundreds of HTTP requests for rendering a simple page tree. That is the reason why people are doing it via a User Macro as in your linked example. Doing it via a real self-written Java Macro would be even better.

I'll say it more clearly: JS is not the right tool here.

> why do you include '> li'?

Because we want the listitems (li) and not the ul. But there's 100 different ways to do this.

sorry I have a mind like a sieve, there it is again Child Selector (“parent > child”) | jQuery API Documentation.

If you're doing this via JS your only choice is to use the Confluence REST API.

thanks

I'll say it more clearly: JS is not the right tool here.

I wish I could create my own use macro or Confluence macro but it is worthless as it won't be allowed within our Confluence currently.

Suggest an answer

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

What project did you transition or start on Confluence with the shift to remote work?

It’s been great to hear from fellow users over the last few weeks about the best tips and fun moments you’ve had working on Confluence since the transition to working remote. I’d love to keep the c...

32 views 2 4
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