How to display a list of sub-pages AND their content on parent page?
Asked by sniadeks:

How to display a list of sub-pages AND their content on parent page?

I know you can put 'exceprt' on every page and display excerpts on parent page. But:

* performance of this solution is unacceptably low
* excerpt are are 'broken' for 'children display' and for 'page tree'

Any solution?  
[](https://community.atlassian.com/t5/Confluence-questions/How-to-display-a-list-of-sub-pages-AND-their-content-on-parent/qaq-p/124515?attachment-id=3587){#link_11891af2d0d0c0}  
[](/tnckb94959/attachments/tnckb94959/confluence-questions/20713/1/image2016-9-23%2013%3A9%3A9.png){#display_11891af2d0d0c0_0}  
[](https://community.atlassian.com/t5/Confluence-questions/How-to-display-a-list-of-sub-pages-AND-their-content-on-parent/qaq-p/124515?attachment-id=3588){#link_11891af2d0d0c0_0}  
[](/tnckb94959/attachments/tnckb94959/confluence-questions/20713/2/image2016-9-23%2018%3A41%3A31.png){#display_11891af2d0d0c0_2}  
[](https://community.atlassian.com/t5/Confluence-questions/How-to-display-a-list-of-sub-pages-AND-their-content-on-parent/qaq-p/124515?attachment-id=3589){#link_11891af2d0d0c0_1}  
[](/tnckb94959/attachments/tnckb94959/confluence-questions/20713/3/image2016-9-26%2010%3A41%3A16.png){#display_11891af2d0d0c0_4}  
[](https://community.atlassian.com/t5/Confluence-questions/How-to-display-a-list-of-sub-pages-AND-their-content-on-parent/qaq-p/124515?attachment-id=3590){#link_11891af2d0d0c0_2}  
[](/tnckb94959/attachments/tnckb94959/confluence-questions/20713/4/image2016-9-26%2010%3A43%3A42.png){#display_11891af2d0d0c0_6}


Answers:
author: Gregor Mirai
body: @Davin Studer's macro has been updated a little bit (code on [github](https://github.com/unidwell/confluence-include-child-pages-macro)) with some new options (page separator, PDF page splitting and filtering on labels).

comments: author: Davin Studer
body: I like what you have added.


author: Milo Test
body: I especially like the page break on PDF export. My only suggestion is that if the page separator is employed, it does not appear in the PDF if PDF page splitting is used.


author: Gregor Mirai
body: Tnx for the idea Milo - the new version pushed to the github has your suggested change :smile:


author: Milo Test
body: Awesome! I can't tell you how long I've been looking for a solution to export a collection of pages to PDF with page breaks; fantastic solution.


author: Kevin Li
body: Is there a way to get all the descendants of the given page, instead of just the children? I would like to display the contents of not only the first-level children, but also all the children in the other levels. Can an option for this be implemented?


author: Melissa C
body: Hello @Gregor Mirai,

I'm attempting with very limited coding skills to modify this code to add it to Sidebar. We want to display the current parent and its children. All other parent and child pages should be hidden.

Has anyone done this? Any insight would be greatly appreciated!


author: Megan McKenna
body: [@Davin Studer](/t5/user/viewprofilepage/user-id/781467) This is such a great macro! Is there anyway to add the ability for it to show all descendants not just the child pages? It would be greatly appreciated!

Thanks!


author: Davin Studer
body: What about a user macro like this?

```
## Developed by: Davin Studer## Date created: 12/4/2014?## @param ShowTitle:title=Show Title|type=boolean|desc=Deselect to remove the title of the child page.|default=true## @param LinkTitle:title=Link Title|type=boolean|desc=Select to turn the titles of the child pages into links to those pages (Show Title must be selected).|default=false## @param Order:title=Order|type=enum|enumValues=Nav Order,Reverse Nav order,Alphabetical,Reverse Alphabetical,Create Date,Reverse Create Date|default=nav order|desc=What order should the child pages be displayed? Nav Order refers to the order of the child pages in the nav tree. Reverse Nav Order simply reverses that.?#set( $containerManagerClass=$content.class.forName('com.atlassian.spring.container.ContainerManager') )#set( $getInstanceMethod=$containerManagerClass.getDeclaredMethod('getInstance',null) )#set( $containerManager=$getInstanceMethod.invoke(null,null) )#set( $containerContext=$containerManager.containerContext )#set( $pageManager=$containerContext.getComponent('pageManager') )?#set( $data = "" )#if( $paramOrder == "Nav Order" || $paramOrder == "Reverse Nav order")	#set( $children =  $pageManager.getPage($content.id).getSortedChildren() )#elseif( $paramOrder == "Alphabetical" || $paramOrder == "Reverse Alphabetical")	#set( $array =  $pageManager.getPage($content.id).getChildren() )	###############################################################	## Could not find a method to get them in Alphabetical order ##	## Must sort them myself ... Bubble sort                     ##	###############################################################	#set( $size = $array.size() )	#foreach( $junk in $array )		#set( $count = -1 )		#foreach( $line in $array )			#set( $count = $count + 1 )			#if( $velocityCount &lt; $size )				#if( $line.getTitle().compareToIgnoreCase($array.get($velocityCount).getTitle()) &gt; 0 )					#set( $tmp = $array.get($velocityCount) )					#set( $junk = $array.set($velocityCount, $line) )					#set( $junk = $array.set($count, $tmp) )				#end			#end		#end	#end	#set( $children = $array)#elseif( $paramOrder == "Create Date" || $paramOrder == "Reverse Create Date")	#set( $children =  $pageManager.getPage($content.id).getChildren() )#end?#foreach( $child in $children )	#set( $include = "" )	#set( $include = $include + '&lt;div class="included-child-page"&gt;')	#if( $paramShowTitle == true )		#if( $paramLinkTitle == true )			#set( $include = $include + '&lt;h1 class="included-child-page-title"&gt;&lt;a href="' + $child.getUrlPath() + '"&gt;' + $child.getTitle() + '&lt;/a&gt;&lt;/h1&gt;' )		#else			#set( $include = $include + '&lt;h1 class="included-child-page-title"&gt;' + $child.getTitle() + '&lt;/h1&gt;')		#end	#end	#set( $include = $include + '&lt;div class="included-child-page-body"&gt;')		#set( $include = $include + '&lt;ac:structured-macro ac:name="include"&gt;')			#set( $include = $include + '&lt;ac:parameter ac:name=""&gt;')				#set( $include = $include + '&lt;ac:link&gt;')					#set( $include = $include + '&lt;ri:page ri:content-title="' + $child.getTitle() + '" ri:space-key="' + $content.spaceKey + '"/&gt;')				#set( $include = $include + '&lt;/ac:link&gt;')			#set( $include = $include + '&lt;/ac:parameter&gt;')		#set( $include = $include + '&lt;/ac:structured-macro&gt;')	#set( $include = $include + '&lt;/div&gt;')	#set( $include = $include + '&lt;/div&gt;')	#if( $paramOrder == "Nav Order"  || $paramOrder == "Alphabetical" || $paramOrder == "Create Date" )		#set( $data = $data + $include )	#else		#set( $data = $include + $data)	#end#end?$data?&lt;style type="text/css"&gt;	.included-child-page {margin-bottom: 30px;}&lt;/style&gt;
```

comments: author: Davin Studer
body: I finally decided to tackle sorting on this. It's been bugging me for a while, but I just never had the time to get to it. I have edited my answer above to include sorting. It also includes the options to show/hide the title and link/unlink the title added by @Milo Grika. I also threw in some css classes (included-child-page, included-child-page-title, and included-child-page-body) so that it can be styled. included-child-page wraps each included child page. included-child-page-title and included-child-page-body are each child page's title and body.


author: Milo Test
body: I'm getting an error:Error rendering macro 'includechildren' : Error occurred rendering template contentThough you totally showed me how to get the simple hide/show/link title thing working! Thanks for the lesson.


author: Davin Studer
body: Hmmm. I've tried it on 5.5.6 and 5.8.6 and it works fine for me on both. I even tried copying and pasting from this post into a new user macro and it works for me. Sure it copied correctly?


author: Milo Test
body: The "double-click to select" fouled me; old-school drag select worked. Sorry for the churn.And thanks for the brilliant code!


author: MichalS
body: I managed to convert 'page title' into 'link' (line number 11):

```
## Developed by: Davin Studer## Date created: 12/4/2014## @noparams#set( $containerManagerClass=$content.class.forName('com.atlassian.spring.container.ContainerManager') )#set( $getInstanceMethod=$containerManagerClass.getDeclaredMethod('getInstance',null) )#set( $containerManager=$getInstanceMethod.invoke(null,null) )#set( $containerContext=$containerManager.containerContext )#set( $pageManager=$containerContext.getComponent('pageManager') )     #foreach($child in $pageManager.getPage($content.id).getSortedChildren())  &lt;h1&gt;&lt;a href=$child.getUrlPath()&gt;$child.getTitle()&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;      &lt;ac:structured-macro ac:name="include"&gt;        &lt;ac:parameter ac:name=""&gt;          &lt;ac:link&gt;            &lt;ri:page ri:content-title="$child.getTitle()" ri:space-key="$content.spaceKey"/&gt;          &lt;/ac:link&gt;        &lt;/ac:parameter&gt;      &lt;/ac:structured-macro&gt;  &lt;/p&gt;#end
```

But **sorting** is still mystery for me. Can anyone help?


author: Siddheshwar mhetre
body: Hi,

I am looking for the same. I want to display all child pages with tree structure using user macro, is this possible?

it should like

image2016-9-23 13:9:9.png

Regards,

Siddheshwar

comments: author: Davin Studer
body: If you just want a tree structure like your screenshot then use the pagetree macro and set the root page to **@self.**


author: Siddheshwar mhetre
body: I want to achieve this by using user macro because i need to change look and feel for the same

Can we change UI of pagetree macro something like

image2016-9-23 18:41:31.png


author: Davin Studer
body: Ok. How about something like this? It will give you a "Collapsible" parameter in the macro setup that will surround the included pages with an expand macro if checked.

```
## Macro Name: include_children
## Visibility: 
## Macro Title: Include Children
## Description: This will include the content from from the child pages onto the parent page that this macro is placed on.
## Categories: Confluence content
## Icon URL: 
## Documentation URL: https://bitbucket.org/fredclown/confluence-user-macros
## Macro Body Processing: No macro body

##############################
## Template: ##
##############################
## Developed By: Davin Studer
## Date Created: 12/4/2014
## Updated by: Milo Grika
## Added: show/hide title, link/unlink title.
## Updated by: Gregor Mirai
## Date updated: 26/1/2016
## Added: page separator, PDF split page marker options.
 
## @param ShowTitle:title=Show Title|type=boolean|desc=Deselect to remove the title of the child page.|default=true
## @param LinkTitle:title=Link Title|type=boolean|desc=Select to turn the titles of the child pages into links to those pages (Show Title must be selected).|default=false
## @param PageSeparator:title=Page Separator|type=boolean|desc=Separate pages with horizontal ruler.|default=false
## @param SplitPages:title=Split Pages|type=boolean|desc=Split pages marker for PDF export will be inserted.|default=false
## @param Collapsible:title=Collapsible|type=boolean|desc=Should the included pages be collapsible?|default=false
## @param FilterLabel:title=Filter on Page Label|type=string|desc=Include only subpages with the specified label.
## @param Order:title=Order|type=enum|enumValues=Nav Order,Reverse Nav Order,Alphabetical,Reverse Alphabetical,Create Date,Reverse Create Date|default=nav order|desc=In what order should the child pages be displayed? Nav Order refers to the order of the child pages in the page tree. Reverse Nav Order simply reverses that.

#set( $containerManagerClass=$content.class.forName('com.atlassian.spring.container.ContainerManager') )
#set( $getInstanceMethod=$containerManagerClass.getDeclaredMethod('getInstance',null) )
#set( $containerManager=$getInstanceMethod.invoke(null,null) )
#set( $containerContext=$containerManager.containerContext )
#set( $pageManager=$containerContext.getComponent('pageManager') )

## Find the array of (sorted) child pages.
#set( $data = "" )
#if( $paramOrder == "Nav Order" || $paramOrder == "Reverse Nav Order" )
    #set( $children = $pageManager.getPage($content.id).getSortedChildren() )
#elseif( $paramOrder == "Alphabetical" || $paramOrder == "Reverse Alphabetical" )
    #set( $array = $pageManager.getPage($content.id).getChildren() )
    ###############################################################
    ## Could not find a method to get them in Alphabetical order ##
    ## Must sort them myself ... Bubble sort ##
    ###############################################################
    #set( $size = $array.size() )
    #foreach( $junk in $array )
        #set( $count = -1 )
        #foreach( $line in $array )
            #set( $count = $count + 1 )
            #if( $velocityCount < $size )
                #if( $line.getTitle().compareToIgnoreCase($array.get($velocityCount).getTitle()) > 0 )
                    #set( $tmp = $array.get($velocityCount) )
                    #set( $junk = $array.set($velocityCount, $line) )
                    #set( $junk = $array.set($count, $tmp) )
                #end
            #end
        #end
    #end
    #set( $children = $array )
#elseif( $paramOrder == "Create Date" || $paramOrder == "Reverse Create Date" )
    #set( $children = $pageManager.getPage($content.id).getChildren() )
#end

## Prepare children data. 
#set( $count = -1 )
#set( $skipped = 0 )
#set( $size = $children.size() )
#foreach( $child in $children )
    ## Create the map of labels for the page.
    #set( $labelsMap = {} )
    #foreach( $label in $child.getLabels() )
        #set( $dummy = $labelsMap.put($label.toString(), 1) )
    #end

    ## Include all pages (when no filter label is specified) or pages with a specific label.
    #if( $paramFilterLabel && !$labelsMap.containsKey($paramFilterLabel) )
        #set( $skipped = $skipped + 1)
    #else
        #set( $count = $count + 1 )
        #set( $include = "" )
        #if ( $paramCollapsible == true )
            #set( $include = $include + '<ac:structured-macro ac:name="expand">' )
            #set( $include = $include + '<ac:parameter ac:name="title">' + $child.getTitle() + '</ac:parameter>' )
            #set( $include = $include + '<ac:rich-text-body>' )
            #set( $include = $include + '<p>' )
        #end
        #set( $include = $include + '<div class="included-child-page">' )

        ## Show title and links.
        #if( $paramShowTitle == true )
            #if( $paramLinkTitle == true )
                #set( $include = $include + '<h1 class="included-child-page-title"><a href="' + $child.getUrlPath() + '">' + $child.getTitle() + '</a></h1>' )
            #else
                #set( $include = $include + '<h1 class="included-child-page-title">' + $child.getTitle() + '</h1>' )
            #end
        #end

        ## Include sub page.
        #set( $include = $include + '<div class="included-child-page-body">' )
            #set( $include = $include + '<ac:structured-macro ac:name="include">' )
                #set( $include = $include + '<ac:parameter ac:name="">' )
                    #set( $include = $include + '<ac:link>' )
                         #set( $include = $include + '<ri:page ri:content-title="' + $child.getTitle() + '" ri:space-key="' + $content.spaceKey + '"/>' )
                    #set( $include = $include + '</ac:link>' )
                #set( $include = $include + '</ac:parameter>' )
            #set( $include = $include + '</ac:structured-macro>' )
        #set( $include = $include + '</div>' )
        #set( $include = $include + '</div>' )
        #if ( $paramCollapsible == true )
            #set( $include = $include + '</p>' )
            #set( $include = $include + '</ac:rich-text-body>' )
            #set( $include = $include + '</ac:structured-macro>' )
        #end

        ## Define sorting order.
        #set( $inOrder = false )
        #if( $paramOrder == "Nav Order" || $paramOrder == "Alphabetical" || $paramOrder == "Create Date" )
            #set( $inOrder = true )
        #end

        ## Find out, whether we are in between pages or not.
        #set( $betweenPages = false )
        #if( $inOrder == true && $count < $size - $skipped - 1 )
            #set( $betweenPages = true )
        #elseif( $inOrder == false && $count > 0 && $count < $size - $skipped )
            #set( $betweenPages = true )
        #end

        ## Include page separator or include page split marker used for PDF exports.
        #if( $betweenPages == true )
            #if( $paramPageSeparator == true )
                #set( $include = $include + '<hr/><br/>' )
            #end
            #if( $paramSplitPages == true )
                #set( $include = $include + '<div style="page-break-before:always;"></div>' )
            #end
        #end

        ## Add page content in order or in reverse order.
        #if( $inOrder == true )
            #set( $data = $data + $include )
        #else
            #set( $data = $include + $data)
        #end
    #end
#end
 
$data
 
<style type="text/css">
    .included-child-page {
        margin-bottom: 30px;
        overflow: hidden;
    }
</style>
```


author: Siddheshwar mhetre
body: Nice Davin,

Almost similar, just a small change, I want to display **child pages** instead of Content of that page

image2016-9-26 10:43:42.png

Cheers

Sid


author: Melissa C
body: @[Davin Studer](https://answers.atlassian.com/questions/users?username=557058%7C4a8825b7-a55d-4713-bc4e-7ad6ac86d221) Help!!!!

GREAT!! Work!!! Thanks for sharing!

I'm attempting with very limited coding skills. To add this Macro to a Parent page but need to modify a bit. I only want to show Parent, Child and h1's of the child. And do not want to show any content. I have played with your code but since my skills are limited I could figure out at remove the display of content.

Any insight would be greatly appreciated!!!!


author: Davin Studer
body: I think what you want could be done with built-in macros. Try this.

On you parent page add the "Children Display" macro with the "Excerpt Display" option set to rich content.

Then on your child pages add an Excerpt macro at the top and inside that macro add a Table of Contents macro and set the options of the TOC macro like this ...

* Outpust Type - list
* List Style - disc
* Minimum Heading Level - 1
* Maximum Heading Level - 1
* Printable - checked
* Absolute URL - checked

Then on your child pages simply put in your content. You parent page will show the child pages and their H1's in a tree format. If you don't like the TOC at the top of the child pages let me know and I can tell you how you can hide that, but still show the headings on the parent page.


author: Melissa C
body: Davin!!!!!

That looks great!!!!! I need to apply this to another use case but I will let you know! I also may want to convert this into a user macro. So that our users can just add a macro and not think about what to select.

Thank you so much!!!!

I'll get back to you tomorrow afternoon


author: Milo Test
body: I'm trying to make the page titles and linkability optional, but my limited programming skills are obviously holding me back.

I've created the parameters:

```
## @param ShowTitle:title=Show Title|type=boolean|desc=Deselect to remove the title of the child page.|default=true## @param LinkTitle:title=Link Title|type=boolean|desc=Select to turn the titles of the child pages into links to those pages (Show Title must be selected).|default=false
```

Which seems to function.

And the conditionals:

```
#if ( $paramShowTitle &amp;&amp; $paramLinkTitle )        &lt;h1&gt;&lt;a href=$child.getUrlPath()&gt;$child.getTitle()&lt;/a&gt;&lt;/h1&gt;        #elseif ( $paramShowTitle &amp;&amp; !$paramLinkTitle )        &lt;h1&gt;$child.getTitle()&lt;/h1&gt;        #end
```

But it shows linked titles no matter which, if any, of the checkboxes are selected. (Removing the conditional altogether makes the titles **not** show, which satisfied my initial need, but options are good.)

Where did I go wrong?


author: MichalS
body: Hi ++@Davin Studer++

This is looking awesome. Will you be so kind and extent this with two simple (I hope so) options?

1. reverse sorting option
2. make 'child title' a link to child page, not just static text

This would be exactly what we need :wink:


author: sniadeks
body: @Alejandro Conde Carrillo

'Children display' macro does not display entire excerpt. This will not do.

Using 'include page' can't be automated (unless you know something I don't know)

@Davin Studer

'Nacitabs' add-on will display tabs, you must click on tam to see what is there. This is not the solution ![sad](/html/@C495B4504065515364EB1894F812B34C/images/emoticons/sad.png "sad")


author: Davin Studer
body: Another option would be to use the [Navitabs add-on](https://marketplace.atlassian.com/plugins/ch.bitvoodoo.confluence.plugins.navitabs). It has a macro to create a tab for each child page and put the contents of each child page into the respective tab.


author: Alejandro Conde Carrillo
body: You could use the [children display macro](https://confluence.atlassian.com/display/DOC/Children+Display+Macro) to display all child pages and some fragment of them (excerpts).

If you want to show the whole content of the page, you will have to use the [include page macro](https://confluence.atlassian.com/display/DOC/Include+Page+Macro). Unfortunately, you will have to add an instance of the macro for every page you want to include and there is not a quick way to insert all child pages.

This also sound like something that could be done creating your own [user macro](https://confluence.atlassian.com/display/DOC/Writing+User+Macros). Unfortunately this may be complex.


Tags: confluence-administration