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

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

sniadeks December 4, 2014

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?

9 answers

1 accepted

3 votes
Answer accepted
Gregor Mirai January 27, 2016

@Davin Studer's macro has been updated a little bit (code on github) with some new options (page separator, PDF page splitting and filtering on labels).

Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 27, 2016

I like what you have added.

Milo Test
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 27, 2016

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.

Gregor Mirai January 28, 2016

Tnx for the idea Milo - the new version pushed to the github has your suggested change smile

Milo Test
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 28, 2016

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.

Kevin Li July 27, 2016

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?

Melissa C February 1, 2017

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!

Megan McKenna November 15, 2017

@Davin Studer 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!

2 votes
Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 4, 2014

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 < $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
 
#foreach( $child in $children )
	#set( $include = "" )
	#set( $include = $include + '<div class="included-child-page">')
	#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
	#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( $paramOrder == "Nav Order"  || $paramOrder == "Alphabetical" || $paramOrder == "Create Date" )
		#set( $data = $data + $include )
	#else
		#set( $data = $include + $data)
	#end
#end
 
$data
 
<style type="text/css">
	.included-child-page {margin-bottom: 30px;}
</style>
Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 26, 2015

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.

Milo Test
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 26, 2015

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

Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 26, 2015

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?

Milo Test
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 27, 2015

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

1 vote
MichalS December 8, 2014

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())
  <h1><a href=$child.getUrlPath()>$child.getTitle()</a></h1>
  <p>
      <ac:structured-macro ac:name="include">
        <ac:parameter ac:name="">
          <ac:link>
            <ri:page ri:content-title="$child.getTitle()" ri:space-key="$content.spaceKey"/>
          </ac:link>
        </ac:parameter>
      </ac:structured-macro>
  </p>
#end

 

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

0 votes
Siddheshwar mhetre
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 22, 2016

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

Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 23, 2016

If you just want a tree structure like your screenshot then use the pagetree macro and set the root page to @self.

Siddheshwar mhetre
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 23, 2016

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

Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 23, 2016

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>
Siddheshwar mhetre
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 25, 2016

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

Melissa C January 27, 2017

@Davin Studer 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!!!!

Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 12, 2017

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.

Melissa C June 12, 2017

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

 

0 votes
Milo Test
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 26, 2015

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?

0 votes
MichalS December 5, 2014

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

 

0 votes
sniadeks December 4, 2014

@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

0 votes
Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 4, 2014

Another option would be to use the Navitabs add-on. It has a macro to create a tab for each child page and put the contents of each child page into the respective tab.

0 votes
Alejandro Conde Carrillo
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 4, 2014

You could use the 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. 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. Unfortunately this may be complex.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events