Monday, February 08, 2010

Confluence wiki: Linking to a diff against a specific old page version

At my office, we use the Confluence wiki for knowledge management.  We recently had some design specifications for a project delivered to us by a 3rd-party consultant; we imported this documentation into Confluence to allow easy tracking of future changes made to the content.

I wanted to be able to add a link to each page along the lines of “click here to see the Confluence diff between the current version of this page, and the 2009 version,” where the aforementioned “2009 version” would be a specific old page version of the page that I would specify when I set up the link on each page.

Unfortunately, Confluence doesn’t provide an “out-of-the-box” way to provide "one click" access such a diff of a specific old page version against the latest version of the page.  You can create a link to a Confluence diff between two specific versions by using the diffpages.action or diffpagesbyversion.action pages that come with Confluence, but both of those take two hard-coded version IDs or page IDs as parameters; they don’t take a parameter or otherwise allow you to specify “latest” as one of the versions to compare.  So you could create a link to a diff between (say) version 1 and version 5 of a page, but that link would become obsolete as new versions beyond 5 were created.

I asked for advice on how to do this (in this thread) on the Atlassian Confluence forum, and got a helpful suggestion from “Rob L.” involving setting up a Confluence user macro to emit the current version of a page, which could then be embedded in a link to a diff page; however, in my Confluence instance at work, I am unable to get a new user macro set up, so while a good solution, it didn’t solve the problem for me.

I then tinkered a bit more on my own, and came up with a way to do this without the need for a user macro. The approach involves using raw HTML (via the Confluence {html} macro) to create a hyperlink with a dummy target (“href”), and then using Javascript (again using the {html} macro) to edit the link target to include the pageId of the Confluence page, which is accessible via the Javascript DOM.

Here's the Confluence markup:

{html}
  <a id="mydiffLink" href="#">Click here to view the diff.</a> 
  <script> 
    document.getElementById('mydiffLink').href=
      "http://myConfluenceHost/confluence/pages/diffpages.action 
      ?originalId=12345678&pageId=" + document.getElementById('pageId').value; 
  </script> 
{html} 

This solution uses diffpages.action rather than diffpagesbyversion.action since the code uses the Confluence page ID, not version ID.

When using this solution, the hard-coded "12345678" in the above example should be replaced with the actual page ID of the old page to compare against.

"http://myConfluenceHost" in the above example should also be replaced with the actual hostname of your Confluence server, of course.

Caveats: This approach relies on (1) the Confluence {html} macro being enabled, and (2) on the user viewing the page having Javascript enabled.