The script on this page, wikihist.cgi, provides a revision history of pages on a [Wikit]-based wiki. It displays a list of all the revisions of a page, and can show the differences, in [WikiDiff] format, between the current page and a specific revision of that page, or between a specific revision of a page and its previous revision. The script relies on four other files. The files are: * utils.tcl: from [Wikit] * format.tcl: also from [Wikit] * worddiff.tcl: from http://pascal.scheffers.net/wikidiff/worddiff.tcl.txt (see [WordDiff] for an explanation) * wikihist.css: actually just a renamed copy of [PS]'s wikit.css at http://pascal.scheffers.net/wikidiff/wikit.css The first three files are sourced into the main script, while the CSS file is pointed to by the generated HTML. To avoid cluttering your CGI directory, it would make sense to wrap these up into a [Starkit]. The script assumes that the Wiki pages have been checked into CVS, and that a directory where the pages can be checked out to exists. This script could probably quite easily be modified to use the tclhist archive, but that is left as an exercise to the reader! OK, the writer has performed the exercise -- see [Wiki Revision History Feature via tclhist]. To deploy this script at another site, you should make the following changes to the script: * replace the initial "exec /home/wiki..." line with the path to your Tcl interpreter * replace all instances of "/usr/local/bin/cvs" with the path to your version of CVS. I didn't just use "cvs" because /usr/local/bin wasn't in the PATH of our webserver. * replace any references to "http://saskatoon/..." with appropriate references for your site * make sure any references to wikihist.css point to your own CSS file * replace the line "cd /home/wiki/wikit/wikipages-co/wiki/daily" to change to a directory where you can check out the Wiki pages from CVS * and I think that's it. Once you've got it installed, point your browser to http://where.ever.you.put.it/wikihist.cgi to get usage instructions. Basically, you can: * get a revision history of a specified page. For example, "wikihist.cgi/12" gets you the history of page 12. * retrieve an old revision of a specified page. For example, "wikihist.cgi/12.5" gets you revision 1.5 of page 12. * compare the latest revision with a specified revision. For example, "wikihist.cgi/12-5" compares the latest revision of page 12 with revision 1.5, and displays it in [WikiDiff] format. * compare two specified revisions. For example, "wikihist.cgi/12-5-2" compares revision 1.5 of page 12 with revision 1.2, and displays it in [WikiDiff] format. If you get errors, you can get your browser to show what they are by enabling the debugging at the end of the script (change "if 0" to "if 1"). This can be integrated into the regular web interface to the Wiki by a short change to web.tcl in the Wikit distribution. After the line that reads: set updated "Updated [cgi_font size=-1 $date]" add the following line: append updated " [nbspace]-[nbspace] Revision History" ---- #!/bin/sh #\ exec /home/wiki/wikit/public_html/wiki/tclkit-solaris-sparc $0 source utils.tcl source format.tcl source worddiff.tcl # This proc returns the contents of the specified revision number # of the specified Wiki page. If no revision number is specified, # the latest revision is obtained. # As coded, this obtains it from the CVS repository. If desired, # this could be recoded to get it from a tclhist archive. proc getPageContents {PageNumber {RevNumber Latest}} { if {[string equal $RevNumber "Latest"]} { catch {exec /usr/local/bin/cvs update -p $PageNumber 2> /dev/null}\ PageContents } else { catch {exec /usr/local/bin/cvs update -r1.$RevNumber -p $PageNumber\ 2> /dev/null} PageContents } return $PageContents } # This proc determines the title of the specified Wiki page. proc getPageTitle {PageNumber} { # Grab a copy of the latest version of the page from CVS. # The title is found on the first line of this page. set PageContents [getPageContents $PageNumber] set TitleLine [lindex [split $PageContents \n] 0] # Now, extract the title from the title line regexp {^Title:\s*(.*)$} $TitleLine junk Title return $Title } # This procedure splits long lines into lines no longer than 80 characters proc splitlongline { line } { set maxlen 80 set thisline "" set lines [list] set opentag 0 foreach word [split $line " "] { if { $opentag || [string first "<" $word] > -1 } { set opentag 1 append thisline " $word" if { [string last ">" $word] > [string last "<" $word] } { set opentag 0 } } else { if { [string equal $thisline ""] } { append thisline $word } else { if { [string length "$thisline $word"] > $maxlen } { if { [llength $lines] > 0 } { set thisline "... $thisline" } lappend lines $thisline set thisline $word } else { append thisline " $word" } } } } if { [llength $lines] > 0 } { set thisline "... $thisline" } lappend lines $thisline return [join $lines \n] } # This proc substitutes any special characters with their HTML equivalents. proc quoteHtml {s} { string map { & & < > > } $s } # For the given Wiki page number, this proc examines the CVS log to determine # the revision number and check-in time of all revisions. The list # returned is ordered from latest revision to earliest revision. # Every revision results in two items in the last, the first being # the minor revision number, and the second being the time that # this revision was checked into CVS, given as the number of # seconds since the Tcl epoch. # # Only major revision # 1 is examined. proc getRevisionList {PageNumber} { set RevisionList {} # Note: for cvs to generate a log, it needs write permission to the # CVS directory. If the Web Server doesn't have this permission, # this script will fail. catch {exec /usr/local/bin/cvs log -r1 -N $PageNumber 2> /dev/null} CvsOutput foreach CvsLine [split $CvsOutput \n] { # Look for a line indicating the revision number. # It will start with "revision 1.", followed by the minor # revision number. if {[regexp {^revision 1.(\d+)} $CvsLine - RevNumber]} { set a $RevNumber } # Also, look for a line indicating the date. # This should follow the revision number in the CVS output, # so we will associate this date with the last revision number we saw. # The date line starts with "date", and the date is in the format # Year/Month/Day Hour:Minute:Second. Tcl is unable to interpret # this date format, so we need to convert it into a format Tcl # can understand before converting it to seconds. if {[regexp {^date} $CvsLine]} { set DateString [string range $CvsLine 6 24] regexp {(\d+)/(\d+)/(\d+) (\d\d:\d\d:\d\d)}\ $DateString junk Year Mon Day Time set RevTime [clock scan "$Mon/$Day/$Year $Time" -gmt 1] lappend RevisionList $RevNumber $RevTime } } return $RevisionList } # This procedure generates the revision history HTML page # for the specified Wiki page number proc genRevisionHistory {PageNumber} { # Generate the content type for the page (HTML) puts "Content-type: text/html" puts "Pragma: no-cache" puts "" # Determine the title of this page set PageTitle [quoteHtml [getPageTitle $PageNumber]] # Now, generate the page header. puts "" puts "" puts "" puts " Revision History of $PageTitle" puts " " puts " " puts { } puts "" puts "" puts "" puts "

" puts " $PageTitle" puts "

" puts " Revision History" puts "" puts "

" puts " Legend: (current) = difference with current version," puts " (last) = difference with preceding version," puts " date = that day's version" puts "

" puts "" # Now, obtain a list of the revisions and the time that they were # checked in. set RevisionList [getRevisionList $PageNumber] # Now that we've got the list of revisions, we need to generate the # revision information to display on the page. puts " " puts "" puts "" puts "" puts "" } (missing part goes here) ---- [KPV] I haven't gone and extracted the utils.tcl, et al files yet but how does this differ from [Wiki History Diff]? [sm] If I understand [Wiki History Diff] correctly, it's a separate application that a user needs to run. Our users wanted something integrated right into the Wiki, so that they could see the history right within their web browser. Other than that, I don't think this script offers any additional functionality over [Wiki History Diff]. ---- [LV]: "Changes to a Tcler's wiki page become available after an offline process occurs once a day. So a page which is first updated today won't have any revisions available until tomorrow - regardless of how many changes were made today." [HJG] I still see this message "There is no revision history for Wiki page 15176" today (2005-12-25), but the page has been created two days ago (2005-12-23). So I wonder at which points in time these revisions are created ? Today (2005-12-26) a whole bunch of revision-entries has appeared, with dates from 2005-12-23 and 2005-12-24 - strange... ---- [Category Wikit] ----