How do I list all pages with titles and, last modified by and updated date based on labels for a specific time period

I have a couple of individual component status pages under a parent page. The sub pages are updated regularly with current status. I want to list all the sub pages, their last modified by user, last modified date, and If these pages were updated in the last 7 days.

This can be done easily using the SQL macro I guess.

My requirements are to list this in tabular format and Is this do-able without using the SQL macro and tweaking the recently updated macro or page properties etc?

7 answers

1 accepted

2 votes
Stephen Deutsch Community Champion Sep 22, 2015

Here's the user macro:

## @noparams
#set ( $descendantPages = $pageManager.getDescendents($content) )
#set ( $compareDate = $action.dateFormatter.getCalendar() )
$compareDate.setTime($content.getCurrentDate())
$compareDate.add(6, -7)
<table>
  <tr>
    <th>Page</th>
    <th>Last Modifier</th>
    <th>Modified Date</th>
    <th>Modified < 7d?</th>
  </tr>
  #foreach ( $page in $descendantPages )
  <tr>
    <td><a href="${req.contextPath}$page.urlPath"> $page.title </a></td>
    <td> $page.lastModifier.name </td>
    <td> $action.dateFormatter.format($page.lastModificationDate) </td>
    <td>
       #set ($pageDate = $action.dateFormatter.getCalendar())
       $pageDate.setTime($page.getLastModificationDate())
      #if ( $pageDate.before($compareDate) )
        <span class="aui-lozenge aui-lozenge-error">NO</span>
      #else
        <span class="aui-lozenge aui-lozenge-success">YES</span>
      #end
    </td>
  </tr>
  #end
</table>

Brilliant. Thanks a lot Stephen, This is exactly what I needed. Please pardon the delay in answering as I dont have rights to directly create a user macro. Please do refer documentation where I can learn more about confluence/JIRA objects as used in the macro.

Stephen Deutsch Community Champion Sep 29, 2015

Hi Abhilash, glad I could help you out. Here is one resource for the Confluence objects used in user macros: https://developer.atlassian.com/confdev/development-resources/confluence-architecture/confluence-internals/velocity-template-overview/confluence-objects-accessible-from-velocity Other than that, it's a lot of Google searching and browsing here on Atlassian Answers. I also have a few User Macros on my bitbucket account: https://bitbucket.org/stephendeutsch/confluence-user-macros

Is there an easy way to modify the above to have an 'Exclude Labels' parameter which will hide any child pages that have the 'meeting-notes' label?

Stephen Deutsch Community Champion Dec 15, 2016

This should work:

## @param ExcludeLabels:title=Labels to exclude|type=string|desc=Enter labels to be excluded, separate multiple labels with comma
#set ( $excludedLabelsString = $paramExcludeLabels + "," )
#set ( $excludedLabelsString = $excludedLabelsString.replace(" ","") )
#set ( $descendantPages = $pageManager.getDescendents($content) )
#set ( $compareDate = $action.dateFormatter.getCalendar() )
$compareDate.setTime($content.getCurrentDate())
$compareDate.add(6, -7)
<table>
  <tr>
    <th>Page</th>
    <th>Last Modifier</th>
    <th>Modified Date</th>
    <th>Modified < 7d?</th>
  </tr>
  #foreach ( $page in $descendantPages )
    #set ( $notContainsExcludedLabel = true )
	#if ( $excludedLabelsString != ",")
      #foreach ( $labelling in $page.getLabellings() )
        #set ( $label = $labelling.getLabel() + "," )
	    #if ( $excludedLabelsString.contains($label) )
	      #set ( $notContainsExcludedLabel = false )
	    #end
	  #end
	#end
    #if ( $notContainsExcludedLabel )
      <tr>
        <td><a href="${req.contextPath}$page.urlPath"> $page.title </a></td>
        <td> $page.lastModifier.name </td>
        <td> $action.dateFormatter.format($page.lastModificationDate) </td>
        <td>
           #set ($pageDate = $action.dateFormatter.getCalendar())
           $pageDate.setTime($page.getLastModificationDate())
          #if ( $pageDate.before($compareDate) )
            <span class="aui-lozenge aui-lozenge-error">NO</span>
          #else
            <span class="aui-lozenge aui-lozenge-success">YES</span>
          #end
        </td>
      </tr>
    #end
  #end
</table>

Thanks so much. That worked a treat! I've modified your code slightly to show pages not modified in the last 365 days and also fixed an issue with the URLs of the pages not showing correctly.

Changing this:

<td><a href="${req.contextPath}$childPage.urlPath"> $page.title </a></td>

To this:

<td><a href="${req.contextPath}$page.urlPath"> $page.title </a></td>

Full code snippet here:

## @param ExcludeLabels:title=Labels to exclude|type=string|desc=Enter labels to be excluded, separate multiple labels with comma
#set ( $excludedLabelsString = $paramExcludeLabels + "," )
#set ( $excludedLabelsString = $excludedLabelsString.replace(" ","") )
#set ( $descendantPages = $pageManager.getDescendents($content) )
#set ( $compareDate = $action.dateFormatter.getCalendar() )
$compareDate.setTime($content.getCurrentDate())
$compareDate.add(6, -365)
<table>
  <tr>
    <th>Page</th>
    <th>Author</th>
    <th>Last Modifier</th>
    <th>Modified Date</th>
    <th>Modified < 365d?</th>
  </tr>
  #foreach ( $page in $descendantPages )
    #set ( $notContainsExcludedLabel = true )
    #if ( $excludedLabelsString != ",")
      #foreach ( $labelling in $page.getLabellings() )
        #set ( $label = $labelling.getLabel() + "," )
        #if ( $excludedLabelsString.contains($label) )
          #set ( $notContainsExcludedLabel = false )
        #end
      #end
    #end
    #if ( $notContainsExcludedLabel )
      <tr>
        <td><a href="${req.contextPath}$page.urlPath"> $page.title </a></td>
        <td> $page.Creator.name </td>
        <td> $page.lastModifier.name </td>
        <td> $action.dateFormatter.format($page.lastModificationDate) </td>
        <td>
           #set ($pageDate = $action.dateFormatter.getCalendar())
           $pageDate.setTime($page.getLastModificationDate())
          #if ( $pageDate.before($compareDate) )
            <span class="aui-lozenge aui-lozenge-error">NO</span>
          #else
            <span class="aui-lozenge aui-lozenge-success">YES</span>
          #end
        </td>
      </tr>
    #end
  #end
</table>

Thanks a bunch!

One more question:

This macro lists all child pages. Is there are way to modify it to make it list all pages within a space, including all sub-spaces? 

Pagination is too much of a stretch too, I'd imagine?

Thanks in advance!

Stephen Deutsch Community Champion Dec 16, 2016

Pagination might be a bit much, but listing all pages should be pretty easy. Just change the line 

#set ( $descendantPages = $pageManager.getDescendents($content) )

to

#set ( $descendantPages = $pageManager.getPages($space, true) )
0 vote
Stephen Deutsch Community Champion Sep 21, 2015

This is certainly possible using a user macro, but your requirements are not very clear. In your title, you say "based on labels" but in your description, you say "pages under a parent page". How are you supposed to determine which pages are in the list?

The Confluence Reporting add-on from Service Rocket.can do all this.

I don't know of a native Confluence way to do this.

Hi Stephen, Sorry my bad. Either way if it is possible, works for me. I have used the recently updated macro with labels on each sub page to aggregate information as of now. But this is restricted only to the information that the macro can retrieve. In an SQL query I am assuming I would be able to pass the Parent PageID to get all the sub pages. The recently updated macro only fetches for a space. Please let me know your feedback on how to do this using a User macro.

Sorry to revive this, great bit of code and really helpful however is there a way to output childpages only and not child and grandchild pages as it currently does with:

#set ( $descendantPages = $pageManager.getDescendents($content) )

 

Stephen Deutsch Community Champion Apr 11, 2017

You should be able to replace it with the following:

#set ( $descendantPages = $content.getChildren() )

I didn't get a chance to test it, but I think that will work.

Hi Stephen. This looks like a great idea.  Can I create the user macro in the new confluence version today?
Also, is it possible to have a choice inside the macro when chosen, to pick which would be the 'parent page'?  then I dont have to modify the target, I could run this from a different page.  Or must I always add this macro to the page that I want to check its children?

Thank you very much!

This sounds like just what I'm looking for (a list of all Space pages along with their created & modified dates), but I can't get it to work; all I get is the following:

<table> <tr> <th>Page</th> <th>Last Modifier</th> <th>Modified Date</th> <th>Modified < 7d?</th> </tr> </table>

What am I doing wrong?

Also running into a similar issue! Any insight?

I have also this error. Did anyone find out how to resolve this ?

Me too. going through the same issue. 

actually I wanted to find all the edits or creation in pages during certain frame of time. So unable to do that. Please suggest some ways to do that.

You need to make sure you have converted the HTML escape characters for &It; and &gt; need to be replaced with the < & > to put them back into html tags. doing that corrected the issue for me

Stephen Deutsch Community Champion Oct 16, 2017

Thanks Ryan. These posts are originally from answers.atlassian.com, and when they were migrated here to the community, they escaped the angle brackets. Maybe if I have time I will go through all my old posts and change them, but it's quite a hassle :(

Thanks Ryan. Appreciate that.

Running through one more error. Actually can you help me to understand how 

$compareDate.add(6, -7)

this piece of code is working. Actually i am unable to figure out that how "add" method is working here by taking any random numbers.

I want to know what does this (6,-7) is indicating ? 

Stephen Deutsch Community Champion Oct 23, 2017

Hi Sandeep,

Confluence uses the Calendar class in the background to store dates (https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html)

and for the add function, you need to include which part of the date you want to modify (Year, Time Zone, Month, Day, Hour, Minutes, Seconds, Milliseconds, etc.).

The number that matches the day part of the date happens to be 6 (so 5 might be month, I don't remember exactly). Adding a negative number to that subtracts that from that particular field. So in essence what this is saying is:

please remove 7 days from this date

Then it uses this date to compare against the last modification date of the page.

Hi Stephen

Thanks a lot for your answer. Appreciate that.

Thanks And Regards

Sandeep Anand

Suggest an answer

Log in or Sign up to answer
Atlassian Community Anniversary

Happy Anniversary, Atlassian Community!

This community is celebrating its one-year anniversary and Atlassian co-founder Mike Cannon-Brookes has all the feels.

Read more
Community showcase
Kesha Thillainayagam
Posted Apr 13, 2018 in Confluence

We want to hear how your non-technical teams are using Confluence!

Hi Community! Kesha (kay-sha) from the Confluence marketing team here! Can you share stories with us on how your non-technical (think Marketing, Sales, HR, legal, etc.) teams are using Confluen...

2,933 views 27 12
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you