Freitag, 21. Januar 2011

Confluence: Include previous versions of a page inside another page

The company I work for had an demand for a confluence plugin/macro that allows to inline pages of older versions. The standard Atlassian include macro just allows to include the most recent version of a page.
With some digging in the Atlassian confluence documentation and with some helpful comments i figured it out by myself and wrote a macro for it.

The macro is based on the render macro from James Mortimer (thx for it) and a code snippet from Azwandi Mohd Aris from Atlassian.

Below is the source of the macro. Just create a new user macro which outputs HTML and is set to have no body.


## declare render macro
## thanks to James Mortimer
## see http://confluence.atlassian.com/display/DISC/Render+any+text+from+a+user+macro
#macro(trimp $xhtml)
## remove leading and trailing 
#if($xhtml.startsWith("",0) && $xhtml.endsWith("
"))
#set($len=$xhtml.length()-$generalUtil.convertToInteger(4))
#set($xhtml=$xhtml.substring(3,$len))
#end
$xhtml
#end
#macro(render $wiki)
#set($globalHelper=$action.getHelper())
#if($content)## i. e. we render a normal page
#set($renderer=$globalHelper.getWikiStyleRenderer())
#set($context=$content.toPageContext())
#set($xhtml=$renderer.convertWikiToXHtml($context, $wiki).replaceAll("\n|\r",""))
#else## we are e. g. in Global Template Preview
#set($xhtml=$globalHelper.renderConfluenceMacro($wiki).replaceAll("\n|\r",""))
#end
#trimp(${xhtml})
#end


## get pagemanager
## thants to Azwandi Mohd Aris [Atlassian]
## see http://confluence.atlassian.com/display/DOC/Include+Page+Macro?focusedCommentId=218279433#comment-218279433
#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'))

## parse the parameters

#set($spacekey=$space.key)
#if($paramspace)
#set($spacekey=$paramspace)
#end

#set($pageversion='0')
#if($paramversion)
#set($pageversion=$paramversion)
#end

#set($pagename="undefined")
#if($parampage)
#set($pagename=$parampage)
#end

## parse the versionstring to an int
#set($versionInt=$generalUtil.convertToInteger($pageversion))

#set($helper=$action.getHelper())
#set($page=$pageManager.getPage($spacekey,$pagename))


## only advance if we have a page
#if($page)
#set($historypage=$pageManager.getOtherVersion($page,$versionInt))
#end

#if($historypage.getId()==$content.getId())
$helper.renderConfluenceMacro("{warning}The version '$pageversion' of page '$pagename' in space '$spacekey' is the same page as this one! Please correct the version information used for the include macro.{warning}")
#elseif($historypage)
#render($historypage.getContent())
#else
$helper.renderConfluenceMacro("{warning}Version '$pageversion' of page '$pagename' in space '$spacekey' not found!{warning}")
#end

Usage:
{pageinclude:page=name of the page|version=x[|space=spacekey]} 
The spacekey is optional. By default the spacekey of the current space is used.

Example:
If you want to include the page "Demonstration" in version 3 from the space with the key "myspace" use the following macro statment
{pageinclude:page=Demonstration|version=3|space=myspace}

Important:
Do not surround the pagename and the spacekey with quotes!

Have fun with it! :-)


P.S. Do not try to include the same page and version as the page that includes the macro. I took this into account! ;-)

5 Kommentare:

  1. Thanks for the great tip. One question: this macro doesn't work with page attachments?

    AntwortenLöschen
  2. No I don't think so. Never thought about it :-)

    AntwortenLöschen
  3. Hey Stefan,
    your macro would be very helpful for us, but we use Confluence 4.3.3 the need changes.
    Do you think about to port your macro to Confluence 4.x, it would be great!

    AntwortenLöschen
  4. Migrated macro to Confluence 5.4. Hope it helps somebody:

    ## @param space:title=SpaceKey|type=string|required=false|desc=Optional space if the page isn't from the current space
    ## @param page:title=PageName|type=string|required=true|desc=The referenced page title
    ## @param version:title=PageVersion|type=string|required=true|desc=The referenced page version to be displayed
    ## @param show:title=ShowVersion|type=boolean|required=false|desc=Defines if the version number is shown just below the content

    ## copied from http://s-weber.blogspot.ch/2011/01/confluence-include-previous-versions-of.html
    ## adapted to Confluence 5.4
    ## Object references:
    ## https://docs.atlassian.com/atlassian-confluence/5.4.4/index.html?com/atlassian/confluence/pages/AbstractPage.html
    ## https://docs.atlassian.com/atlassian-confluence/5.4.4/com/atlassian/confluence/core/ContentEntityObject.html

    ## get pagemanager
    ## thants to Azwandi Mohd Aris [Atlassian]
    ## see http://confluence.atlassian.com/display/DOC/Include+Page+Macro?focusedCommentId=218279433#comment-218279433
    #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'))

    ## parse the parameters

    #set($spacekey=$space.key)
    #if($paramspace)
    #set($spacekey=$paramspace)
    #end

    #set($pageversion='0')
    #if($paramversion)
    #set($pageversion=$paramversion)
    #end

    #set($pagename="undefined")
    #if($parampage)
    #set($pagename=$parampage)
    #end

    ## parse the versionstring to an int
    #set($versionInt=$generalUtil.convertToInteger($pageversion))

    #set($helper=$action.getHelper())
    #set($page=$pageManager.getPage($spacekey,$pagename))

    ## only advance if we have a page
    #if($page)
    #set($historypage=$pageManager.getOtherVersion($page,$versionInt))
    #end

    #if($historypage.getId()==$content.getId())
    $helper.renderConfluenceMacro("{warning}The version '$pageversion' of page '$pagename' in space '$spacekey' is the same page as this one! Please correct the version information used for the include macro.{warning}")
    #elseif($historypage)
    ##$historypage.getId()
    ##$historypage.getTitle()
    ##$historypage.getClass()
    ##$historypage.getUrlPath()
    ##$historypage.getBodyContent()
    #set($mainBodyContent=$historypage.getBodyContent())
    ##mainBodyContent=$mainBodyContent.getClass()
    #set($mainPage=$mainBodyContent.getContent())
    ##mainPage=$mainPage.getClass()
    ##$mainPage.getBodyContent()
    ##mainPageType=$mainPage.getType()
    #set($pageContent=$mainPage.getBodyContent())
    ##pageContent=$pageContent.getClass()
    $pageContent.getBody()
    #if($paramshow==true)
    Version : $paramversion
    #end
    #else
    $helper.renderConfluenceMacro("{warning}Version '$pageversion' of page '$pagename' in space '$spacekey' not found!{warning}")
    #end

    AntwortenLöschen
  5. Is somebody figured out how to include attachment in this macro?
    Thank you

    Patrick

    AntwortenLöschen