A simple script to mark a version of a page as approved
This groovy script is designed to be put into a user macro. It stores an approved version number for the page as a page property. If the displayed version is not the approved version, it renders a warning, and a link to the approved version. If the user is in a certain group it renders a link to allow the approval of the current page.
This is all to comply with ISO 9001 document control, which requires formal approval of all QMS doc and changes.
Why a script and not a plugin? Couldn't be bothered with the maven awfulness! If anyone wants to turn it into a proper plugin, be my guest.
Copy this code into a user macro, assuming the script plugin & groovy is installed.
{groovy:output=wiki}
def user = com.atlassian.confluence.user.AuthenticatedUserThreadLocal.user
def page = context.entity
def ua = bucket.container.ContainerManager.getComponent("userAccessor")
def group = ua.getGroup("QMSApprovers")
def cpm = bucket.container.ContainerManager.getComponent("contentPropertyManager")
def pm = bucket.container.ContainerManager.getComponent("pageManager")
def approveVersion = request.getParameter("approveVersion")
def propPage = page
if (!page.isLatestVersion())
propPage = page.getLatestVersion()
String approvedVersion = cpm.getStringProperty(propPage,"approved.version")
// is the current user in the appropriate group?
boolean approver = ua.hasMembership(group,user)
// has the approve link been clicked?
if (approveVersion!=null && approver)
{
approvedVersion = approveVersion
cpm.setStringProperty(page,"approved.version",approveVersion)
}
//is this the approved version?
if (approvedVersion==null || !approvedVersion.equals( context.entity.version.toString() ) )
{
// render a warning
if (approvedVersion==null)
{
print "{warning:title=Warning}This document has not been formally approved."
}
else
{
print "{warning:title=Warning}This is not the currently approved version of this document."
if (page.isLatestVersion() )
{
print " The approved version is *"
def oldVersion = pm.getPageByVersion(page, new Integer(approvedVersion) )
print "{html}<a href='"
print contextPath
print oldVersion.urlPath
print "'>"
print approvedVersion
print "</a>.{html}* "
}
}
// if user in the right group, render a link to allow approval
if (approver)
{
println ""
print " {html}<a href='"
print contextPath
print page.urlPath
print "?approveVersion="
print page.version
print "'>Approve this version<a>{html}"
}
println "{warning}"
}
else
{
// approved version
println "{tip}This is the formally approved version of this document.{tip}"
}
{groovy}

Comments (7)
Nov 05
Justin Hickman says:
It should be noted that you're using security by obscurity when it comes to appr...It should be noted that you're using security by obscurity when it comes to approving the page. All it takes is someone to add:
to their URL, and it's "approved"
This could be avoided by checking "hasMembership()" in the section where it's setting the page properties.
Nov 05
Jon Nermut says:
feel free to fix itfeel free to fix it
Nov 05
Alain Moran says:
Gotta love open-sourceGotta love open-source
Nov 05
Justin Hickman says:
Have you thought of any way to make this global to a space? You could add ...Have you thought of any way to make this global to a space? You could add it to a template, but that requires the person to remember and use the template in order to get that ability. It also is up to the editor to keep the macro in the page or not. Having it outside of the page content can also help when it comes to exporting to PDF, et al. You may not want the banner displayed in an export.
I tried modifying my layout to do:
#includePage($helper.spaceKey ".approvalInclude")That doesn't work as the approval will end up being on .approvalInclude rather than the page it's included on. This would require the macro to know about the page it's included in, rather than where the macro exists.
Nov 06
Jon Nermut says:
It's a nasty hack, but you could add another line before your #includePage to pu...It's a nasty hack, but you could add another line before your #includePage to put the current page in a request attribute (its probably $page or $pageContext or something), then get it out again in the script.
Nov 06
Alain Moran says:
try this #includePage("${helper.spaceKey}.approvalInclude")try this
#includePage("${helper.spaceKey}.approvalInclude")Nov 06
Justin Hickman says:
From going through the Confluence Javadoc, I was able to figure out an easier so...From going through the Confluence Javadoc, I was able to figure out an easier solution:
$helper.renderConfluenceMacro("{approval}")From initial tests, it does appear to be working correctly and against the current page.