Using Confluence REST API to post generated html table (PHP) without getting http 400 status code?

6.4k views Asked by At

My goal is to create a page with a table in a confluence wiki using the provided REST API that can be easily edited by users of the wiki using the WYSIWYG editor after the page has been created.

I have taken apart texts and put into different categories into an array of arrays, and then generated an html table (a string) out of this, which works great.

However posting this raw html table (in $htmlTable) as content to the REST API

$data = array("type" => "page", "title" => someTitle, 
       "space" => array("key" => "$uploadSpace"), 
       "body" => array("storage" => array("value" => "$htmlTable", "representation" => "storage")));

returns a 400 statusCode error. Obviously because the input is not properly escaped using htmlspecialchars for encoding the string into html, but how would I create a stuctured input that translates into an html table otherwise?

I have attempted to pass my html table with a confluence macro that renders the html input into a table for viewing:

$data = array("type" => "page", "title" => someTitle,
       "space" => array("key" => "$uploadSpace"), 
       "body" => array("storage" => array("value" => "<ac:structured-macro ac:name=\"html\"><ac:plain-text-body><![CDATA[$htmlTable]]></ac:plain-text-body></ac:structured-macro>", "representation" => "storage")));

This renders my html table on the page, however this fails the easily editable in WYSIWYG requirement as users of the wiki would see the html code contained in a macro afterwards.

Thank you very much in advance.

2

There are 2 answers

0
Drupal Syb On

After a long struggle, found the fix.

Add the macro code over your HTML content.

$bodyFormatted = '<ac:structured-macro ac:name="html"><ac:plain-text-body><![CDATA['.$bodyFormatted.']]></ac:plain-text-body></ac:structured-macro>';

$bodyFormatted variable holds the HTML content.

$data['type'] = 'page';
$data['title'] = $articleData["title"].time();
$data['space']['key'] = $articleData["container"];
$data['body']['storage']['value'] = $bodyFormatted;
$data['body']['storage']['representation'] = 'storage';

Encode to json and pass thru REST. Before that one important process, where I failed.

"Enabling the HTML Macro" Ref: https://confluence.atlassian.com/conf55/confluence-user-s-guide/creating-content/using-the-editor/working-with-macros/html-macro

Inspite of warnings, enable the mentioned module (html (html-xhtml))

Process your API calls and now check the content. Hope you are done. Once the work is done, disable the modules, to prevent the cross scripting attacks.

0
unickshaxor On

You need to modify your table to use the Confluence Wiki Markup to markup the table. As an example, the html table:

$data = "<table>
         <tr><th>First Name</th><th>Last Name</th><th>GPA</th></tr>
         <tr><td>Bob</td><td>Jones</td><td>3.52</td></tr>
         <tr><td>Fred</td><td>Smith</td><td>2.89</td></tr>
         </table>";

Should be written as:

$data = "||First Name||Last Name||GPA||
         |Bob|Jones|3.52|
         |Fred|Smith|2.89|";

Then, when you you do the update / insert via REST, change the 'representation' from 'storage' to 'wiki'. (And remove the html macro wrapper)

$data = array("type" => "page", "title" => someTitle,
             "space" => array("key" => "$uploadSpace"), 
             "body" => array("**wiki**" => array("value" => "$htmlTable", "representation" => "**wiki**")));

This will give you a native, wysiwyg Confluence table.

The 'storage' representation indicates that the body test is already converted to the format that Confluence uses internally to store the content. You want to insert using 'wiki', and let Confluence handle any conversions for you.