Call User macro inside User macro..
Asked by Kenn North:

There is a similar question on here, but it's not quite what I'm looking for. We are upgrading from 3.5.3 to 5.1.x and we are converting all our user macros.

We currently have macros that start an HTML table and then one the ends that table. A third macro outputs a row for that table. This works fine in 3.5.3, but not in 5.1.x

I took the two macros that start and end the table and just created a wrapper macro that starts and ends the table and outputs $body, however, the macro that generates the row does not get rendered as HTML.

Is is possible to have a User macro that is called inside another User Macro (and therefore rendered as part of $body) to output as HTML?


Answers:
author: Steve Goldberg
body: I've found a workaround, which works for me - I don't know if it'll help you.

1. In the container macro, remove the macro body and add a class to the \<tbody\> tag - I've used "jhactbody" as that's meaningful for me.
2. In your 'row' macro, wrap the \<tr\> tags in a \<table\> and \<tbody\> tag (this will prevent Confluence from stripping out the \<tr\>s). Now put a class on your \<tr\> tag - I've used "jhactrow".
3. At the bottom of your 'row' macro, put the following JS (change the class names as necessary):  

   ```
   &lt;script type="text/javascript"&gt;	$('.jhactbody').append($('.jhactrow'));&lt;/script&gt;
   ```

4. Create a page with the table macro at the top and then all your rows below it.

What this script does is every time the macro is called, it creates a table, a table body, and a table row with your stuff in it and then adds it to the bottom of the \<tbody\> element in your main table.

Confluence being Confluence, you can use its strength against it (some coding Jujutsu as it were) as it then strips out the empty table that you used to create the row. The result is a perfectly formed table as you wanted it. The only annoying thing is the JS that is being called each time.

comments: author: Kenn North
body: I tried this, and it generates a series of separate tables for each row, so now the columns, for example, isn't the same width. It's a clever workaround, but I can't quite get it to work right. Is your table displaying as one solid table?

I guess I could set the cell width and remove the top and bottom margins... Still baffled why Confluence doesn't just render the HTML I provide, who cares if it's not wrapped in a \<table\> tag.


author: Steve Goldberg
body: Yeah, it works fine for me. If it's generating separate tables for each then it sounds like the JS isn't working.

So in the first macro (which has no body), I have the following table:

```
&lt;table&gt;	&lt;thead&gt;		&lt;tr&gt;			&lt;th&gt;&lt;/th&gt;			&lt;th&gt;&lt;/th&gt;			&lt;th&gt;&lt;/th&gt;			&lt;th&gt;&lt;/th&gt;			&lt;th&gt;&lt;/th&gt;			&lt;th&gt;&lt;/th&gt;			&lt;th&gt;&lt;/th&gt;			&lt;th&gt;&lt;/th&gt;		&lt;/tr&gt;	&lt;/thead&gt;	&lt;tbody class="jhactbody"&gt;&lt;/tbody&gt;&lt;/table&gt;
```

(I've stripped out all data pertinent to my work).

In the second macro, after I've declared parameters etc, I have the second macro (which also has no body):

```
&lt;table&gt;	&lt;tbody&gt;		&lt;tr class="jhactrow"&gt;			&lt;td&gt;&lt;/td&gt;			&lt;td&gt;&lt;/td&gt;			&lt;td&gt;&lt;/td&gt;			&lt;td&gt;&lt;/td&gt;			&lt;td&gt;&lt;/td&gt;			&lt;td&gt;&lt;/td&gt;			&lt;td&gt;&lt;/td&gt;			&lt;td&gt;&lt;/td&gt;		&lt;/tr&gt;	&lt;/tbody&gt;&lt;/table&gt;&lt;script type="text/javascript"&gt;	$('.jhactbody').append($('.jhactrow'));&lt;/script&gt;
```

You then put one of the first macro in the page and then as many of the second macros as you like. They should be moved into the top table.


author: Kenn North
body: Thanks Steve.. You answered the immediate issue. There is still the question of why the macro doesn't output HTML, but looks like no one knows.


author: David at David Simpson Apps
body: As @CharlesH says, try this approach <http://davidsimpson.me/2012/01/24/on-converting-wiki-markup-based-user-macros-for-use-with-confluence-4/>

I can confirm that it works for both Confluence 4.x and 5.x

It also removes the grunt work out of the process.


author: CharlesH
body: Did you try following the approach described by David Simpson (AppFusions) here: <http://davidsimpson.me/2012/01/24/on-converting-wiki-markup-based-user-macros-for-use-with-confluence-4/>

This certainly worked for me in Confluence 4. Not tried it in 5 yet, but I'd suggest giving it a go.


author: Steve Goldberg
body: I am having the exact same problem. While it would be nice to find a workaround in this thread, I'd also quite like an explanation from Atlassian about what is going on here. Why is it stripping out the \<td\> and \<tr\> tags?

comments: author: ahuffman
body: I'm seeing this as well. Not only is the rendered option stripping out the \<h1\> tags, it also removes all the text within those tags.


author: Kenn North
body: Thanks for the help, but that is showing how you call a user macro from within a user macro at the time of User macro development.

I'm talking about a user instantiating a user macro on a page that allows for a rendered body, and then in the body of that user macro they instantiate a different user macro that is supposed to render HTML.

When the body of the wrapping user macro is rendered it removes all the HTML markup from the output of the user macro begin called.

This is getting confusing to explain, here is a simple example of using macros to build a table that wraps rows. The row (User Macro 2) needs to output HTML, but when it's rendered as part of the body of User Macro 1, the HTML markup is stripped out.

User macro 1

```
## Macro has a body: Y#### @noparams&lt;table&gt;&lt;tr&gt;&lt;th&gt;Column 1&lt;/th&gt;&lt;th&gt;Column 2&lt;/th&gt;&lt;/tr&gt;$body&lt;/table&gt;
```

User Macro 2

```
## Macro has a body: N#### @param paramcolumn1:title=Column1|type=string|desc=## @param paramcolumn1:title=Column2|type=string|desc=##&lt;tr&gt;&lt;td&gt;$!paramcolumn1&lt;/td&gt;&lt;td&gt;$!paramcolumn2&lt;/td&gt;&lt;/tr&gt;
```

comments: author: CharlesH
body: Can you indicate what the body processing should be for macro 1 please? As you've moved from 3.5 to 5, you'll see that the choices for this are different:

* No macro body
* Escaped
* Unrendered
* Rendered

My gut feel is that you should be using the "Rendered" option, but it would be worth experimenting with the escaped and unrendered options if that doesn't work.


author: Kenn North
body: I've tried all 4, Rendered is what I would "expect" it to be based on the description and behavior of other macros. The other 3 options just make things worse.


Tags: confluence-administration

user-macro