It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

How do you add template variables as macro parameters or in plain text macro bodies?

Prior to Confluence 4.3, it was easy to add template variables anywhere in the template. Is this capability gone in Confluence 4.3?

Also, when editing a template and using Insert Wiki Markup, I keep getting "Wiki Markup Conversion Errors - error:Bad Request" when the inserted wiki contains a macro (like {info} for example). Same problem on Confluence 5.0.

12 answers

4 votes
Kim Poulsen Oct 01, 2015

I have done some tinkering on this subject and have come up with a (less than perfect) user macro that will work in a lot of cases. "Less than perfect"? Well it seems the user macro rendring of $body ruins the layout of sections on the page if JIRA macros are included. In practise this makes side-by-side JIRA issue tables impossible, outside of that I have tried sections and columns with success.

Macro name: applytemplatevars
Macro Title: Apply Template Variables
Description: This macro encases other macros so that template variables can be transferred to them.
Categories: Confluence Content
Macro Body Processing: Rendered
## Macro title: applytemplatevars
## Macro has a body: Y
## Body processing: Rendered
## Output: body with replaced variables
## Developed by: Kim Poulsen
## Date created: 28/09/2015
## Installed by: <you?>
## @noparams
## Fish out the parameter section of the body:
#set ($lbody = $body)
#set ($idx = $lbody.indexOf("</p"))
#set ($params = $lbody.substring(3, $idx))
## Replace the body with the real body (without the variable section)
#set ($body = $lbody.substring($idx))
## This version accepts <name>=<value>|<name>=<value>|... type specification
#foreach($v in $params.split("[|]"))
  ## Fish out variable names and values:
  #set ($varArr = [])
  #foreach($i in $v.split("[=]"))
    #set ($retval = $varArr.add($i) )
  #set ($vn = $varArr.get(0) )
  #set ($vv = $varArr.get(1) )
  ## And do the replacement:
  #set ($body = $body.replaceAll($vn, $vv) )
  ##  Change the page title as well (dangerous: The page will change title, and possibly get lost.)
  #set ($title = $content.getTitle() )
  #set ($title = $title.replaceAll($vn, $vv) )


Use it like this:

{applyfromtemplate} mySuperTemplatevar=$mySuperTemplatevar|myOthervar=$templateVar2|myNonTemplateVAR=Yes we can substitute arbitrary strings not only template vars.   Instance other macros and use the "mySuperTemplatevar" and "myOthervar" anywhere. The macro will replace them with the template vars. The variable list will not be rendered on the view page. {/applyfromtemplate}


I'd appreciate any input on how to not get output ruined when using JIRA macros in a rendered $body.

Edit: Obviously the macro can also be used without template variables. Just type in the string you want to substitute and all is good too.

Kim Poulsen Oct 01, 2015

To add to the case it seems Confluence does more to the body after the JIRA macro: <div class="hidden"> <textarea id="refresh-wiki-2035414160"> <input id="refresh-page-id-2035414160" type="text" value="7375841" /> </div> <p /> </div> <p /><h5 id="... ... </textarea> The "class=hidden" effectively eats everything below that point on the page. And the textarea converts it all to a string, so bye bye remaining page.

Dougi B Nov 18, 2015

@Kim Poulsen thank you for your comment. I got this working, but it replaces variables in the body-output only. It does not replace variables, I pass to the makro as parameter (as the title of this thread is suggesting). Is that correct?

Kim Poulsen Nov 19, 2015

@Dougi B The macro should replace all variables in text and macros put into the body of the "applytemplatevars" macro. I cannot post images here, but lets try this in text:

/ VAR1=Hello|VAR2=World
This would print on screen:
Hello World

Another one:

/ VAR1=Hello|VAR2=World
/Panel(title=VAR1) /
/ VAR2 /
/------ /
Other text from the big VAR2 /
This would print on screen:
/ Hello /
/----------- /
/ World /
/----------- /
Other text from the big World /


So in the case I set the Title of the panel to the value "VAR1" and the body of the panel to "VAR2" I also re-use VAR2. You can use this together with template variables "$myVar" if you like. It looks like the mechanism is as simple as Confluence substituting $myVar when generating the draft page. So using them as variable values in this macro, you get to input data from the template generation stage too. It get's complicated without images, so I hope you understand the crude drawings above. The only case where I cannot get this to work is when using JIRA macros - which was actually where I started looking into this :-)

Edit: Fix formatting.

Dougi B Nov 19, 2015

I think the title in your example was replaced in the output of the macro. In my case I pass an URL to an macro, which downloads and inspect a file. Unfortunately I don't have access to the logsfiles, but I verified this by adding the value "MyValue" of the parameter ("MyParametername") to the output. It gets replaced. but when I split the value I get "My" "Parametername" in the output. The parameter has never been replaced.

Kim Poulsen Nov 20, 2015

@Dougi B: Okay so you have something like: URL=http://my-fileserver.sth/filespec.txt And a Macro, where you specify an URL field with "URL" in it? I must admit that I haven't tried to use it in such a clever way :-) I've tested it out now though, and while replacement does happen as expected (i.e. URL gets substituted) it uses whatever formatting Confluence choses for links. This means wrapping stuff in <span> tags etc. I can get to the point where I need to whitelist a site by putting in the HTML include macro "http:/" and define MYVAR=my/path/to/the/page.html Confluence does not do any further automatic formatting on a string like that and actually attempts to retrieve a page from mysite. Then again, this macro is not a generic solution, it manipulates the page content before rendering, and any pre-processing Confluence might think is a good idea could interfere with any good intentions here :-)

David Curran Apr 07, 2016

Pretty nifty macro.  One problem I'm having.  It seems to work for macros like "panel" and "info" but not for macros like "recently-updated" or "contentbylabel". The variable text doesn't get replaced in those.  Any thoughts as to why?

Kim Poulsen Apr 17, 2016

Sorry, I have no idea. The macro is pretty brute force in nature as it simply replaces all matching stings with the substitution string, so perhaps these macros hide their parameters in a format this macro doesn't get around to do substitutions in. If you take a look at the storage format of the page with those macros you might get a hint of this. I envision that label names are encapsulated in some extra tags for instance.

Kevin Mote May 10, 2016

This is such a tantalizing macro, but I can't figure out how to use it. (I'm new to user macros). I created a new User Macro, cut&paste your code into the Template field, and saved it. Then in a sandbox, I typed \{applytemplatevars}  (without the forward slash). But when I previewed the page, all I saw was "Error rendering macro 'applytemplatevars' : Error occurred rendering template content". Can you please provide a step by step example of exactly how to use this code? THank you!

Deleted user May 11, 2016

Hey @Kim Poulsen,


thanks for your user macro. Unfortunately I have a strange bug which makes it unusable to me:

The macro works in the macro preview and in the page preview, correctly replacing the variables. But once the page is saved, the substitution does not work anymore and the variable name is displayed again.

Do you have any clue what could cause such behaviour?

Kim Poulsen May 12, 2016

Hi @Kevin Mote.

  One case where the macro will throw "Error rendering" is if you are not specifying any variables in the first line of the macro body. I assume you have checked the "Rendered" button in the User Macro editor.

So when looking at the storage format, it should look like this:

<ac:structured-macro ac:macro-id="aca752e4-35f4-4534-a87d-d4d164e0ed35" ac:name="applytemplatevars" ac:schema-version="1">
<ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
<ac:rich-text-body> <p>VAR1=Test</p> <p>Here's: VAR1</p>

Here I have just defined one variable "VAR1=Test", and use it in the sentence below: "Here's VAR1".

Want more variables? Just specify them in this format:

VAR1=Tara|VAR2=Tarb|<and so on>

They just have to be in the first line, that's all.

I hope this helps you and possibly others.

Kim Poulsen May 12, 2016

Hi @Alexander Schöcke.

 The macro is quite brute force in nature, so maybe the places where you try to substitute, are not exposed in such a way that e.g. a variable VAR1 is like this in the storage format.

 If you look at the page storage format, you should be able to see what's going on. I know that drop-downs, people selectors and stuff like that is not usable with this macro for the above reason.

I have a hard time saying more, as I don't know on what you try to apply the substitution, but I hope this helps a little.


Deleted user May 12, 2016

Hey @Kim Poulsen,


thank you for your answer. I basically tried this on an empty page in order to rule out any incompatibilities with other macros or the like, so the storage format ist not more than this:


<ac:macro ac:name="applytemplatevars">
    <ac:parameter ac:name="atlassian-macro-output-type">BLOCK</ac:parameter>
        <p>Display VAR1</p>
Kim Poulsen May 12, 2016

Hi @Alexander Schöcke,

We're running Confluence 5.8.9 btw.

You storage format looks almost like my example above. I wonder if the "BLOCK" vs. "INLINE" makes the difference? I cannot get the macro here to use "BLOCK", so I wonder where that might come from.

The other difference is that your storage format is not a "structured-macro", but just a "macro", so something is wrong here. Also here I cannot reproduce that output.

I'm sorry, I don't think I have the insight to aid on this one.

Sam Hasler Oct 26, 2016

This doesn't appear to work if the macro you insert into the body is a user macro. I suspect it is due to the order user macros are rendered in, or because there is only one render "pass", both of which are outside of our control.

Farshin Arya Oct 09, 2018

Hi @Kim Poulsen,

I have tried using your code in a user macro but I get rendering error, so I assumed I am doing something very basic wrong.

What I am going to achieve is to create a page template, define a $projecKey variable in the beginning of it and some macros following that. When the user creates a page from the template, they are asked to insert project key and the key should be delivered to like 10 other macros, which those will use the key in a jQuery for fetching data from some REST API. I only need and have one variable for all of those macros and that only one is the project key which I defined in the first line of template.

That said, I do as follows:

1- Create a user macro, set it to rendered and paste your code inside it (untouched)

2- I a page template, insert a variable from top menu and call it projectKey. So it makes it green and shows as $projectKey

3- Following that, I insert the macro I created in step number 1. 

Question here is, at this stage what should be written inside this macro, I just inserted in?

"mySuperTemplatevar=$projectKey|", this leaves me with rendering error.

Kim Poulsen Oct 09, 2018

Hi @Farshin Arya

Here's a very basic example (now in color):


when generating the page:


And rendered:



From what you write I suspect you write "$projectKey", not the "green $projectKey".

Farshin Arya Oct 09, 2018

Tack for the magic, @Kim Poulsen :) it worked!

The only thing was that $body returned the variable's value with some extra tags like: <p></p>thevalue</p>. Had to run (/<(.|\n)*?>/g, '') on it.

1 vote

Hallo Bob and Eddie

I'm not exactly sure what you're asking ;) but could it be the same as this discussion in our doc space?

Cheers, Sarah

Daniel Brice Mar 03, 2013
Sarah that discussion is related. I'm surprised this feature is missing in 4.3 & 5 as I make use of it in many of my templates and don't want to loose that functionality when we upgrade. Is there not any other way to use variables as macro parameters? Some plugin perhaps?

Must have missed this earlier. It covers part of it. The part about variables in plain text bodies is not covered.

Daniel Brice Jul 25, 2013

Is there a bug or improvement open for this issue? Is there any way to work around this problem?

I use this feature in many of my Confluence 4 templates for many reasons. Here's one example:

Enter label of projects: @PROJECT_LABEL@
{checklist:name=Project Information|parent=Home|usecanvas=false|label=@PROJECT_LABEL@|depth=4}
{checklist-input:cols=20|heading=Tech Lead|rows=1}
{checklist-input:cols=40|heading=JIRA Versions|rows=1}
{checklist-input:cols=20|heading=Bamboo Key|rows=1}

1 vote
MoBe Apr 27, 2014

Any updates about this? I'm currently evaluating Confluence and I need some functionality like this one... +1

Joey Corea Mar 08, 2015

You can watch this issue, but I wouldn't hold your breath

1 vote
Thunder Stumpges Jun 30, 2014

Just ran into this issue as well. CONF-3324 has been open a surprisingly long time with no real "desire" from Atlassian to fix it. I'm a little baffled honestly with how good their product seems to be. Not sure how this issue could be viewed by them as a "nice to have" for their Blueprints feature. To me it is just straight broken if this doesn't work, they lose all their power to be used for anything beyond a very simple formatted text page. Very disappointed right now. :(

0 votes
Eddie Webb Mar 01, 2013

Perhaps I am misunderstanding, but in Confluence 5 you can define variables anywhere, including inside macros like the info box.

The "insert wiki markup" (ctrl+shift+d) also seems to work for me.

Space tools > content tools > page templates

Joey Corea Mar 08, 2015

No, the question is asking about macro _parameters_. You are referring to inserting variables into the macro body.

0 votes
Eddie Webb Mar 01, 2013

Sorry for my confusion before. Even the former work around of declaring the variable outside the scope of the macro parameters does not make them replaced within the parameter. Have you "poked" atlassian about this, or submitted a ticket? Seems some functionality has regressed.

Yes, I poked a couple of times.

BTW, I don't think the Variables insert thing is very obvious for people that new the old way of doing things. I took me a while to notice that in the editor. So actually your post would be helpful for some other folks.

Yes, I poked a couple of times.

BTW, I don't think the Variables insert thing is very obvious for people that knew the old way of doing things. I took me a while to notice that in the editor. So actually your post would be helpful for some other folks.

0 votes
iribe May 03, 2013

We also have got a similar issue.

We want to create a page template using one variable (issue key) that will be used by the SQL macro.

This mechanism will allow the users to have a page already pre formated with a set of macros (here this is SQL macros) using the value of an issue required during the page creation.

The template will look like:

Type the value of the issue_key: $variable
select i.issue_key, i.issue_type, i.timespent
from issue
where i.issue_key = 'Eval of $variable' (here I would like to have the value of the variable selected)

Does somebody help us ?

0 votes
Angel Arcos Feb 12, 2014

Any updates about this? I'm currently evaluating Confluence and I need some functionality like this one...

0 votes
Daniel Brice Feb 12, 2014

I think the closest you'll get to this functionality is through writing your own User Macros:

0 votes
Kate York Oct 08, 2015

I was able to pass a template variable to a macro in the following way:

  1. Create a new Macro 
  2. $body will be the value of the template variable. Use this however you need to. In my case I am hooking into the Content By Label macro by passing a dynamic label parameter from the template.
  3. In the page template edit mode add a new template variable 
  4. Add the macro into the page template. Click into the body of the macro and choose Insert > Your variable.
## Macro title: My Macro
## Developed by: My Name
## Date created: dd/mm/yyyy
## Installed by: My Name
## @noparams
&lt;ac:macro ac:name="contentbylabel"&gt;
&lt;ac:parameter ac:name="label"&gt;$body&lt;/ac:parameter&gt;
&lt;ac:parameter ac:name="operator"&gt;AND&lt;/ac:parameter&gt;

Simple but it works.

Kim Poulsen Oct 13, 2015

This is a simple solution, and that is an advantage. The disadvantage is that it is also tailored for a single purpose because you have to insert any and all macros you want in here, or create one user macro for each type of default macro you want to use template variables with. Another disadvantage is that you can only use a single variable in this case. My solution works for any number of variables and can substitute any number of contained macros and any number of fields in those macros. The disadvantage is that JIRA macros seem to render themselves in a way that puts the remainder of the page into a hidden <textfield>. This is where your solution comes in handy because the use is them limited to e.g. the JIRA macros. Thanks for sharing.

Dougi B Nov 17, 2015

I tried this solution in confluence 5.4.2 but it doesn't work for me. Is this working in JIRA only? I pass 4 variables as macro parameter to the macro, two of them are urls. the macro only gets $variablename. I tried both, insert to the body of the wrapper-macro: $variablename or $$variablename.

Kim Poulsen Nov 17, 2015

@Dougi B: The macro Kate describes only works because the $body variable contains the body of the macro, and the body of the macro becomes the label text in this case. In other words, you will not have any other variable names available to you in this example. My own solution further above splits the $body into separate variables, which are then substituted into other macros instantiated inside the body of the wrapper macro.

Suggest an answer

Log in or Sign up to answer
This widget could not be displayed.
This widget could not be displayed.
Community showcase
Published in Confluence

6 Awesome Ways to Apply Trello, JIRA and Confluence to your Project

I attended  Atlassian Summit 2019  and learned a lot from the presenters, attendees and knowledgeable Atlassian product managers. The presentations I attended focused on applying Agile, pla...

2,109 views 11 27
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you