Usage of param type confluence-content in macro for pages with a semicolon in the Title

Hello there

We use a macro that creates a fully customizable button on a page that points to another page in confluence. To select the page, I use the parameter type “confluence-content”:

## @param link:title=Targetpage|type=confluence-content|required=true|desc=Some confluence page

Later I generate a link out of it using the following code:

#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 ($ss='')
#set ($sp='')

#foreach ($p in $paramlink.split(":"))
#if ($ss=='')
#set ($ss=$p)
#else
#set ($sp=$p)
#end
#end
#if ($sp=='')
#set ($sp=$ss)
#set ($ss=$space.key)
#end

#set ($page=$pageManager.getPage($ss, $sp))


<div style="text-align: center;" onclick="location.href='$req.contextPath$page.urlPath'";>$paramlink</div>

This works fine until the page title contains a semicolon (’ or “& # 39 ;” for java). If this is the case, the var “$page” is empty and so no page is found.

I can’t figure out how to get this working again and any help would be appreciated!

Thanks a lot
nks

It seems that I just found the answer myself.

If I add the following line just before the “foreach” part and change this a little bit, it seems to work now.

...
#set($newlink = $paramlink.replace("&#39;", "'"))

foreach ($p in $newlink.split(":"))
...

The problem with macro parameters of type “confluence-content” is that they lose data when they pass the value to your macro via the execute method’s Map<String, String> parameters.

They lose data by concatentating the space-key and content-title attributes into one string value and by not prepending the space-key when the confluence-content is for the space that the macro lives in. There is an implicit space-key value for “this” space and that ruins everything. No way to tell if the text before the colon is a space key or part of the title.

A “confluence-content” parameter exists in the markup as a link with a SEPARATE space-key and content-title:

<ac:parameter ac:name="MyPageParameter"><ac:link><ri:page ri:space-key="TEST" ri:content-title="Chapter 1: The Beginning" /></ac:link></ac:parameter>

When this parameter is passed to the macro the value is “TEST:Chapter1: The Beginning”. The space key is essentially lost.

It is lost because if the confluence-content parameter is for a page that is in the SAME space as the macro editor that was used to set the value of the parameter there is NO ri:space-key attribute in the markup and it becomes:

<ac:parameter ac:name="MyPageParameter"><ac:link><ri:page ri:content-title="Chapter 1: The Beginning" /></ac:link></ac:parameter>

and the value of the parameter, as passed to the execute() method of your macro is: “Chapter 1: The Beginning”.

SO… there is no way to tell if String.split(":") is giving you a space key or some junk that was at the beginning of the title of the page.

As far as I can tell it is impossible to reliably get the space-key from the value of this type of macro parameter from the execute method of your macro.

Here is how I would fix it if I were Atlassian:
I’d provide complex values for “confluence-content” macro parameters in the Map<String, String> parameters that is passed to the execute() method of a macro:

key: “MyPageParameter”, value: “TEST:Chapter 1: The Beginning” (this is useless but has to be there for backwards compatibility)
key: “MyPageParameter.content-title”, value: “Chapter 1: The Beginning”
key: “MyPageParameter.space-key”, value: “TEST”

This problem is significantly hurting the reliability of a big macro of ours.

2 Likes