Translations of this page?:

Diff

This set of changes allows diffs between any two versions of the existing file.

Sample Screenshots

First (original) Screenshot

Second Screenshot

update by ryan on 1-15-2006 (new, more expansive and descriptive layout in a table)

  • I created a more organized and symetrical diff layout. I can post the code if interested, leave a message.
  • I would prefer to just have a single column of radio button or checkboxes like phpwiki (I think two radio buttons per line is too confusing). I doubt anyone would need to do a reverse diff and the second radio button may just confuse some users. I'd also like to highlight the table row onclick, but I don't know how to do that.

To use the alternative layout above, you need change the function html_revisions() in /inc/html.php in addition to all the other changes described on this page for implement the multiple diffs. They are all HTML layout changes. I don't have a specific list of the changes, but the function is rather short. So, I pasted this function in its entirety below. Do these changes last AFTER you've done all the other changes described on this page.

/**
 * list old revisions
 *
 * @author Andreas Gohr <andi@splitbrain.org>
 */
function html_revisions(){
  global $ID;
  global $INFO;
  global $conf;
  global $lang;
  $revisions = getRevisions($ID); 
  $date = @date($conf['dformat'],$INFO['lastmod']);
  //print '</td>';
  print p_locale_xhtml('revisions');
  print '<h1>'.$ID.'</h1>'; 
  print '<form method="get" action="doku.php">';
  print '<input type="hidden" name="id" value="'.$ID.'" />';
  print '<input type="hidden" name="do" value="diff" />';
  print ' <input type="submit" value="Compare selected versions" class="button"/>
          <img src="lib/images/diff.png"> = COMPARE TO CURRENT VERSION
          <center>
          <table cellpadding="2" width="100%">
          <tr align="center" style="background-color: #eeeeee">
          <td width="20%">Select Any Two:</td>
          <td width="10%">Compare to <br>Current Version:</br></td>
          <td width="15%">Edited on:</td>
          <td width="15%">View Page Version:</td>
          <td width="30%">Editor\'s comments (if any):</td>
          <td nowrap="1">Edited by:</td>
          </tr>
          </table></center>
 
          <center><table cellpadding="2" id="compare-table" width="100%">';
 
 // print '<ul>';
  if($INFO['exists']){
  //  print ($INFO['minor']) ? '<li class="minor">' : '<li>';
    	print '<tr align="center"><td width="20%"><input type="radio" value="" name="rev" checked="checked">';
		//print '<img src="'.DOKU_BASE.'lib/images/blank.gif" border="0" width="15" height="11" alt="" />';
	    print '<input type="radio" value="" name="rev2"  style="visibility:hidden"></td>';
     print ' <td width="10%">';
	print '('.$lang['current'].')';
	print '</td>';
	print '<td width="15%">';
    print $date;
    print '</td>';
 
    print '<td width="15%"><a class="wikilink1" href="'.wl($ID).'">current';
	// print '.$ID.';
	print '</a> </td><td width="30%">';
    print $INFO['sum'];
    print '</td><td nowrap="1"><span class="user">';
    print $INFO['editor'];
    print '</span>';
    print '</td></tr>';
  }
  $checked = false;
 
  foreach($revisions as $rev){
    $date = date($conf['dformat'],$rev);
    $info = getRevisionInfo($ID,$rev);
    print '<tr align="center"><td width="20%">';
    //print ($info['minor']) ? '<li class="minor">' : '<li>';
	print '<a href="'.wl($ID,"rev=$rev,do=diff").'">';
    print '</a>';
	print '<input type="radio" name="rev" value="'.$rev.'">';
 
	if( !$checked ){
		print '<input type="radio" name="rev2" checked="checked" value="'.$rev.'">';
		$checked = true;
      }
	else
		print '<input type="radio" name="rev2" value="'.$rev.'"></td>';
 
	 print '<td width="10%"> <a href="'.wl($ID,"rev=$rev,do=diff").'">';
    $p = array();
    $p['src']    = DOKU_BASE.'lib/images/diff.png';
    $p['border'] = 0;
    $p['width']  = 15;
    $p['height'] = 11;
    $p['title']  = $lang['diff'];
    $p['alt']    = $lang['diff'];
    $att = buildAttributes($p);
    print "<img $att />";
    print '</a> </td>';
	print '<td width="15%">';
    print $date;
    print '</td>';
    print '<td width="15%"><a class="wikilink1" href="'.wl($ID,"rev=$rev").'">older version</a></td><td width="30%"> ';
    print htmlspecialchars($info['sum']);
    print '</td><td nowrap="1"><span class="user">';
    if($info['user']){
      print $info['user'];
    }else{
      print $info['ip'];
    }
    print '</span></td></tr>';
 
 //   print '</li>';
  }
  // print '</ul>';
  print '</table></center><input type="submit" value="Compare selected versions" class="button"/></form>';
 
}

How it works

I also started extending the diff function to (maybe?) allow linking to the current revision with a rev tag even though it hasn't been archived in the attic yet.

Linking to a diff between two revs looks this:

http://localhost/doku.php?id=start&do=diff&rev=1110935500&rev2=1110848901
Parameter Required Default Notes
id yes NA The usual wiki id
do yes NA The diff action
rev no current The first revision date to diff
rev2 no current The second revision date to diff

DOKU.PHP DIFF

This is a diff against the 2006-03-09 release. The only change was to parse out rev2 in addition to rev.

--- doku.php.orig       2006-04-15 18:58:52.000000000 -0700
+++ doku.php    2006-04-15 17:57:15.000000000 -0700
@@ -20,6 +20,7 @@
   $QUERY = trim($_REQUEST['id']);
   $ID    = getID();
   $REV   = $_REQUEST['rev'];
+  $REV2  = $_REQUEST['rev2'];
   $ACT   = $_REQUEST['do'];
   $IDX   = $_REQUEST['idx'];
   $DATE  = $_REQUEST['date'];

HTML.PHP DIFF

This diff modifies two functions html_revisions() and html_diff().

html_revisions() now creates a form that links back to doku.php with rev and rev2 parameters for the files to be compared. The method uses two columns of radio buttons similar to MediaWiki (but not nearly as fancy).

html_diff() is now modifed (it is very verbose to document the how) to compare rev vs rev2, current vs rev2 or rev vs current. If rev or rev2 is the same as the filemtime of the current revision, rev/rev2 will be set to '' to force a compare to the current revision. [Checking against the current filemtime appears to work, and I think it should always work.]

--- html.php.orig 2006-03-09 12:32:34.000000000 -0800
+++ html.php   2006-04-15 18:48:19.000000000 -0700
@@ -421,11 +421,22 @@
   $date = @date($conf['dformat'],$INFO['lastmod']);
 
   print p_locale_xhtml('revisions');
-  print '<ul>';
+  if ($revisions) {
+    print '<form method="get" action="doku.php">';
+    print '<input type="hidden" name="id" value="'.$ID.'" />';
+    print '<input type="hidden" name="do" value="diff" />';
+    print '<input type="submit" value="Compare selected versions" class="button"/>';
+  }
+  print '<ul>'."\n";
   if($INFO['exists']){
     print ($INFO['minor']) ? '<li class="minor">' : '<li>';
     print '<div class="li">';
 
+    if ($revisions) {
+      print '<input type="radio" value="" name="rev2" style="visibility:hidden"/>';
+      print '<input type="radio" value="" name="rev" checked="checked"/>';
+    }
+
     print $date;
 
     print ' <img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" /> ';
@@ -442,12 +453,24 @@
     print '</li>';
   }
 
+  $checked = false;
+
   foreach($revisions as $rev){
     $date = date($conf['dformat'],$rev);
     $info = getRevisionInfo($ID,$rev);
 
     print ($info['minor']) ? '<li class="minor">' : '<li>';
     print '<div class="li">';
+
+    if( !$checked ){
+        print '<input type="radio" name="rev2" checked="checked" value="'.$rev.'"/>';
+        $checked = true;
+    }
+    else
+        print '<input type="radio" name="rev2" value="'.$rev.'"/>';
+
+    print '<input type="radio" name="rev" value="'.$rev.'"/>';
+
     print $date;
 
     print ' <a href="'.wl($ID,"rev=$rev,do=diff").'">';
@@ -473,9 +496,14 @@
     print '</span>';
 
     print '</div>';
-    print '</li>';
+    print '</li>'."\n";
   }
   print '</ul>';
+
+  if ($revisions) {
+    print '<input type="submit" value="Compare selected versions" class="button"/>';
+    print '</form>';
+  }
 }
 
 /**
@@ -736,16 +764,53 @@
   require_once(DOKU_INC.'inc/DifferenceEngine.php');
   global $ID;
   global $REV;
+  global $REV2;
   global $lang;
   global $conf;
-  if($text){
+
+  // get the filetime of the current revision
+  // might use this for allowing the RSS feed to show diffs of current to old
+  $filetime = filemtime(wikiFN($ID));
+
+  if( $REV == $filetime ){
+    //print 'Filetime matched, using current<br>';
+    $REV = '';
+  }
+
+  if( $REV2 == $filetime ){
+    //print 'Filetime matched, using current<br>';
+    $REV2 = '';
+  }
+
+  if($text){ // diff for conflicts
     $df  = new Diff(split("\n",htmlspecialchars(rawWiki($ID,''))),
                     split("\n",htmlspecialchars(cleanText($text))));
     $left  = '<a class="wikilink1" href="'.wl($ID).'">'.
               $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a>'.
               $lang['current'];
     $right = $lang['yours'];
-  }else{
+  }elseif($REV && $REV2){ // diff between versions
+    $df  = new Diff(split("\n",htmlspecialchars(rawWiki($ID,$REV2))),
+                    split("\n",htmlspecialchars(rawWiki($ID,$REV))));
+
+    $left  = '<a class="wikilink1" href="'.wl($ID,"rev=$REV2").'">'.
+              $ID.' '.date($conf['dformat'],$REV2).'</a>';
+
+    $right = '<a class="wikilink1" href="'.wl($ID,"rev=$REV").'">'.
+              $ID.' '.date($conf['dformat'],$REV).'</a>';
+
+  }elseif($REV2){ // diff between current and REV2
+    $df  = new Diff(split("\n",htmlspecialchars(rawWiki($ID,$REV2))),
+                    split("\n",htmlspecialchars(rawWiki($ID,$REV))));
+
+    $left = '<a class="wikilink1" href="'.wl($ID,"rev=$REV2").'">'.
+              $ID.' '.date($conf['dformat'],$REV2).'</a>';
+
+    $right  = '<a class="wikilink1" href="'.wl($ID).'">'.
+              $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a> '.
+              $lang['current'];
+
+  }elseif($REV){ // diff between latest and selected rev
     if($REV){
       $r = $REV;
     }else{
@@ -761,6 +826,8 @@
     $right = '<a class="wikilink1" href="'.wl($ID).'">'.
               $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a> '.
               $lang['current'];
+  }else{
+    print '<p>Nothing to diff</p>';
   }
   $tdf = new TableDiffFormatter();
   if($intro) print p_locale_xhtml('diff');

Update for Dokuwiki 2006-11-06

I was able to update the code to work with Dokuwiki 2006-11-06. Being that I have (well, now had) no idea about php nor almost about html, I managed to merge the changes with the new version. So first thanks to the original authors for the work.

Anyway, having said this, it seems to work pretty well, as far as I could test it. It does revision existence and no-revision checking, works with revisions spanning more than one page, and all other thigs I could imagine. Feel free to correct whatever could be wrong or improved.

Inigo Aldazabal 2007/01/31 23:05

Here you have the diffs and the already patched files… (right click and save as, please)

multidiff for Dokuwiki 2006-11-06, “old” layout
diffs patched files
doku.php.diff
html.php.oldlayout.diff
multidiff_oldlayout.zip
Please, could you place these diffs outside your wiki installation, because they were interpreted by dokuwiki while downloading.
Thanks – Uwe
They are not within any wiki. I just created a folder named dokuwiki in my web server and put the files there. You should have no problem (I don't have, at least) right-clicking on the links and choosing “save link as” or something similar (my system is not in english, so I don't know the exact quote). They are just plain text files.
Anyway, later today I will add some zip files with the full new files instead of the diffs. – Inigo
Sorry, it was my Opera. With Firefox they are okay. – Uwe

With these patches you will get something like

multidiff //"old"// layout

If you want the alternative layout go on reading…

Alternative layout

I also include, in the same spirit as the original patch, a Dokuwiki 2006-11-06 updated html_revisions() function (whithin /inc/html.php file) with the alternative layout, in case you like it.

As the original author does, I suggest you to try the previous changes and, if everything seems to work ok, proceed with this if you want. You can download the function (no diffs here) from (right click etc) html_revisions_function.php.txt

If you are on the risky side, you can just just apply the following diffs or already patched files instead of the previous ones over the original Dokuwiki 2006-11-06 files (doku.php.diff is the same as before, just html.php.newlayout.diff includes the modified layout). At least for me it works with no problems.

multidiff for Dokuwiki 2006-11-06, “new” layout
diffs patched files
doku.php.diff
html.php.newlayout.diff
multidiff_newlayout.zip

As you can see, it is slightly modified from the original one.

multidiff //"new"// layout


Update for DokuWiki Release Candidate 2007-05-24

I was using Inigo's multidiff fix for the 2006-11-06 release. (Thanks, Inigo!) Then I updated to the new release candidate and was left without my beloved multidiff function. :( So I ran a file comparison with the new html.php file and applied the fix. (It uses the original layout.) It seems to work pretty well so far, so I thought others who updated might find it useful. Below are the patched files. — J. Lee 2007-05-30 04:12

doku.zip

html.zip

Oh, I forgot. Back when I applied the fix to 2006-11-06 I put some spaces between the radio buttons, so it might look slightly different from Inigo's original layout. Also, more importantly, I entered the variable $lang['compareselected'] into the input buttons, so the buttons will come out blank unless you replace the variable with text of your own or add the following line or its linguistic equivalent to the lang.php file of your choice.
$lang['compareselected'] = 'Compare selected versions';

Update for DokuWiki Version 2007-06-26b

The following diffs can be applied from the corresponding sub-directories by calling

patch -p1 < xxx.diff

doku.php.diff (./doku.php)

--- old/doku.php        2007-06-26 20:27:15.000000000 +0200
+++ new/doku.php        2007-05-30 10:55:18.000000000 +0200
@@ -22,6 +22,8 @@
   $ID    = getID();
   $NS    = getNS($ID);
   $REV   = $_REQUEST['rev'];
+  //multidiff revision
+  $REV2  = $_REQUEST['rev2'];
   $ACT   = $_REQUEST['do'];
   $IDX   = $_REQUEST['idx'];
   $DATE  = $_REQUEST['date'];

html.php.diff (./inc/html.php)

--- old/html.php	2007-06-26 20:27:15.000000000 +0200
+++ new/html.php	2007-05-30 10:56:12.000000000 +0200
@@ -444,10 +444,25 @@
   $date = @date($conf['dformat'],$INFO['lastmod']);
 
   print p_locale_xhtml('revisions');
-  print '<ul>';
+  
+  //multi-compare revision
+  if ($revisions) {
+    print '<form method="get" action="doku.php">';
+    print '<input type="hidden" name="id" value="'.$ID.'" />';
+    print '<input type="hidden" name="do" value="diff" />';
+    print '<input type="submit" value="'.$lang['compareselected'].'" class="button"/>';
+  }
+  
+  print '<ul style="margin-top: 10px;">'."\n";
   if($INFO['exists'] && $first==0){
     print (isset($INFO['meta']) && isset($INFO['meta']['last_change']) && $INFO['meta']['last_change']['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) ? '<li class="minor">' : '<li>';
     print '<div class="li">';
+    
+    //multi-compare revision
+    if ($revisions) {
+      print '<input type="radio" value="" name="rev2" style="visibility:hidden"/> ';
+      print '<input type="radio" value="" name="rev" checked="checked"/> ';
+    }
 
     print $date;
 
@@ -465,6 +480,10 @@
     print '</div>';
     print '</li>';
   }
+  
+  //multi-compare revision
+  $checked = false;
+
 
   foreach($revisions as $rev){
     $date = date($conf['dformat'],$rev);
@@ -472,9 +491,32 @@
 
     print ($info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) ? '<li class="minor">' : '<li>';
     print '<div class="li">';
+    
+    //multi-compare revision
+    //print $date;
+
+    if(@file_exists(wikiFN($ID,$rev))){
+    //start multi-compare revision
+            if( !$checked ){
+            print '<input type="radio" name="rev2" checked="checked" value="'.$rev.'"/> ';
+            $checked = true;
+        }
+        else{
+            print '<input type="radio" name="rev2" value="'.$rev.'"/> ';
+        }
+        print '<input type="radio" name="rev" value="'.$rev.'"/> ';
+    }
+    else{
+      print '<input type="radio" value="" name="rev2" style="visibility:hidden"/> ';
+      print '<input type="radio" value="" name="rev" style="visibility:hidden"/> ';
+    }
+
+
     print $date;
 
     if(@file_exists(wikiFN($ID,$rev))){
+    //end multi-compare revision
+    
       print ' <a href="'.wl($ID,"rev=$rev,do=diff").'">';
       $p = array();
       $p['src']    = DOKU_BASE.'lib/images/diff.png';
@@ -506,6 +548,13 @@
     print '</li>';
   }
   print '</ul>';
+  
+  //multi-compare revision
+    if ($revisions) {
+  
+    print '<input type="submit" value="'.$lang['compareselected'].'" class="button"/>';
+    print '</form>';
+  }
 
   print '<div class="pagenav">';
   $last = $first + $conf['recent'];
@@ -782,17 +831,63 @@
   require_once(DOKU_INC.'inc/DifferenceEngine.php');
   global $ID;
   global $REV;
+  //multi-compare revision
+  global $REV2;
+  
   global $lang;
   global $conf;
+  
+  //start multi-compare revision
+  // get the filetime of the current revision
+  // might use this for allowing the RSS feed to show diffs of current to old
+  $filetime = filemtime(wikiFN($ID));
 
-  if($text){
+  if( $REV == $filetime ){
+    //print 'Filetime matched, using current<br>';
+    $REV = '';
+  }
+
+  if( $REV2 == $filetime ){
+    //print 'Filetime matched, using current<br>';
+    $REV2 = '';
+  }
+  //end multi-compare revision
+
+  if($text){ // diff for conflicts
     $df  = new Diff(explode("\n",htmlspecialchars(rawWiki($ID,''))),
                     explode("\n",htmlspecialchars(cleanText($text))));
     $left  = '<a class="wikilink1" href="'.wl($ID).'">'.
               $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a>'.
               $lang['current'];
     $right = $lang['yours'];
-  }else{
+  }
+  
+  //start multi-compare revision
+  elseif($REV && $REV2){ // diff between versions
+    $df  = new Diff(explode("\n",htmlspecialchars(rawWiki($ID,$REV2))),
+                    explode("\n",htmlspecialchars(rawWiki($ID,$REV))));
+
+    $left  = '<a class="wikilink1" href="'.wl($ID,"rev=$REV2").'">'.
+              $ID.' '.date($conf['dformat'],$REV2).'</a>';
+
+    $right = '<a class="wikilink1" href="'.wl($ID,"rev=$REV").'">'.
+              $ID.' '.date($conf['dformat'],$REV).'</a>';
+
+  }elseif($REV2){ // diff between current and REV2
+    $df  = new Diff(explode("\n",htmlspecialchars(rawWiki($ID,$REV2))),
+                    explode("\n",htmlspecialchars(rawWiki($ID,$REV))));
+
+    $left = '<a class="wikilink1" href="'.wl($ID,"rev=$REV2").'">'.
+              $ID.' '.date($conf['dformat'],$REV2).'</a>';
+
+    $right  = '<a class="wikilink1" href="'.wl($ID).'">'.
+              $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a> '.
+              $lang['current'];
+
+  }
+  //end multi-compare revision  
+  
+  else{
     //check if current revision exist
     if(!@file_exists(wikiFN($ID))){
       $revs = getRevisions($ID, 0, 2);

lang.php.diff (./inc/lang/en/lang.php)

--- old/lang.php        2007-06-26 20:27:15.000000000 +0200
+++ new/lang.php        2007-09-29 11:18:21.000000000 +0200
@@ -233,4 +233,6 @@
 
 $lang['i_retry']      = 'Retry';
 
+$lang['compareselected'] = 'Compare selected versions';
+
 //Setup VIM: ex: et ts=2 enc=utf-8 :

Discussion

This is an excellent modification, hopefully it'll make into the core. I'm so used to MoinMoin and Mediawiki and being able to compare arbitrary versions. Has anyone implemented this in a recent version of Dokuwiki – January 4, 2006

Has anyone tested this to see if it works? Super mod! – January 13, 2006

I'm answering my own question, yes it works! I tried it and then customized it a bit per the 2nd screenshot above. –ryan Jan 15, 2006

I've fixed some minor bugs in multidiff code (no form is shown now if there is only one revision of the file, the radio buttons for the newest release are now in right column (like they’re in Mediawiki) and the diff view also behaves accordingly to radio buttons positions (it swapped the side where each revision should be shown)). You can get here the diff file against 2006-03-09 releaseDaniel Calviño Sánchez 2006/04/28

Daniel, A diff against the 2006-03-09 release may not be much good. You should at least try to use a current snaphot of the development version. Irregardless of whether this gets added, you could now implement it as an action plugin. Action plugins are currently develonly but will be available in the next release of DokuWiki. — Christopher Smith 2006-09-11 14:40

Here is an update for doku.php and html.php - DokuWiki version 2006-11-06. You can download these versions here: Update for doku.php, html.php Doku Wiki release 2006-11-06Lemsi 2007-01-23 11:08

Hello Lemsi, when I download doku.php or html.php I get the error:
Warning: main(/www/htdocs/w005f11d/downloads/doku-wiki/inc/init.php): failed to open stream: No such file or directory in /www/htdocs/w005f11d/downloads/doku-wiki/doku.php on line 12

> Means, they were interpreted by php. Could you please put them as *.php.txt on your site ?
Thanke, Uwe

I added a new section with an update for Dokuwiki 2006-11-06. Is my first time with php, so be carefull. Anyway, I tested it quite carefully and, at least for me, seems to work with no problemas at all. Please report any problems you find with it… — Inigo Aldazabal 2007/01/31 23:05

Can someone please upload the patche files for 2007-06-26b? “Patch for Windows” (Yes, I know… ;-) ) doesn't work correctly and I really need this patch… — Alfred 2007/11/27

 
wiki/discussion/diff.txt · Last modified: 2008/03/01 21:29 by 79.120.68.111
 
Imprint Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
WikiForumIRCBugsTranslate