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

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

Bob Swift OSS (Bob Swift Atlassian Apps)
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.
February 25, 2013

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

1 accepted

4 votes
Answer accepted
Kim Poulsen
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.
October 1, 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
Template:
## 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) )
  #end
  #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) )
  $content.setTitle($title)
*#
#end
$body

 

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
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.
October 1, 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 November 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
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.
November 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:

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

Another one:

/applytemplatevars/
/ 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 November 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
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.
November 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:/mysite.com/MYVAR" 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 :-)

currand60 April 7, 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
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.
April 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
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.
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
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.
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>
</ac:rich-text-body>
</ac:structured-macro>

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
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.
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>
    <ac:rich-text-body>
        <p>VAR1=WARRRRR</p>
        <p>Display VAR1</p>
    </ac:rich-text-body>
</ac:macro>
Kim Poulsen
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.
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 October 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 October 9, 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
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.
October 9, 2018

Hi @Farshin Arya

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

image.png

when generating the page:

image.png

And rendered:

image.png

 

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

Farshin Arya October 9, 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.

2 votes
Deleted user June 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. :(

1 vote
MoBe April 27, 2014

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

joeycorea March 8, 2015

You can watch this issue, but I wouldn't hold your breath https://jira.atlassian.com/browse/CONF-3324

1 vote
SarahA
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.
March 3, 2013

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?

https://confluence.atlassian.com/display/DOC/Confluence+4.3-RC1+Release+Notes?focusedCommentId=297669317#comment-297669317

Cheers, Sarah

Daniel Brice March 3, 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?
Bob Swift OSS (Bob Swift Atlassian Apps)
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.
March 7, 2013

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

Daniel Brice July 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}
{checklist}

0 votes
yorky001 October 8, 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;
&lt;/ac:macro&gt;

Simple but it works.

Kim Poulsen
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.
October 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 November 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
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.
November 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.

0 votes
Daniel Brice February 12, 2014

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

https://confluence.atlassian.com/display/DOC/Adding%2C+Editing+and+Removing+User+Macros

0 votes
Angel Arcos February 12, 2014

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

0 votes
iribe May 3, 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
{sql:dataSource=xxxx}
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)
{sql}
......
......

Does somebody help us ?

0 votes
Bob Swift OSS (Bob Swift Atlassian Apps)
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.
March 3, 2013

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
Bob Swift OSS (Bob Swift Atlassian Apps)
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.
March 1, 2013

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.

0 votes
EddieW
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.
March 1, 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.

0 votes
EddieW
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.
March 1, 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

https://confluence.atlassian.com/display/DOC/Adding+a+Template

joeycorea March 8, 2015

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

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events