I guess July is WordPress plugin month here at movingtofreedom.org, because here comes another one. This one was instigated by another Scott.
Scott Rosenberg wrote last week about the “mutability of online content” and the challenges news organizations face in handling changes and corrections to stories, and concluded that versioning made sense in journalism as a way to build trust. Readers can see all of the changes since publication so that there’s no sense of something being swept under the rug. The Drupal CMS has modules for making revisions publicly viewable, and of course this is a key feature of Wikipedia.
Scott noted that WordPress already stores revisions, and suggested a plugin could make old versions accessible to visitors. Looking to demo the idea on his blog, he later asked if any WordPress developers were intrigued. At first I was only intrigued enough to dig up an existing plugin by D’Arcy Norman that did some of what he was looking for: “Post Revision Display,” but gradually became invested in the challenge of making this thing happen. And here it is!
(And here is Scott’s post about the plugin: “Change is good, but show your work.”)
What It Does
It’s pretty simple. Drop the post-revision-display.php file into your plugins dir and activate it, and you’ll see a list of post-publication revisions at the end of single post pages:

Click on the link for a revision, and you’ll get a page showing that revision along with the “diffs” between the old revision and the current revision:

If you have the standard <?php wp_head() ?> hook in your theme’s header.php file, the plugin will add to the page header when an old revision is displayed:
<meta name="robots" content="noindex, nofollow" />
To prevent indexing by search engines. (This is what Wikipedia does on its revision pages and I think is a good idea here as well.)
That’s all you have to do in the default “automatic” mode to start using the plugin, but you’ll likely want to add some CSS to make the header note stand out and have the diffs look all spiffy as in the screenshot.
CSS
The diff styling is modeled after how the WordPress admin pages show comparisons. You may want to use similar styles as I did:
table.diff { width: 100%; }
table.diff th { text-align: left; }
table.diff .diff-deletedline { background-color:#fdd;
width: 50%; }
table.diff .diff-deletedline del { background-color:#f99;
text-decoration: none; }
table.diff .diff-addedline { background-color:#dfd;
width: 50%; }
table.diff .diff-addedline ins { background-color:#9f9;
text-decoration: none; }
table.diff .diff-context { display: none; }
This is entirely up to you, of course, but I’ll make a few comments about my choices:
thI like left-alignment for the headers here..diff-deletedline, .diff-addedlineThese are the WordPress colors. I added 50% as the width. They are used for the column headers also, showing previous revision datetime and current revision..diff-deletedline delWordPress color. Default text-decoration fordelseems to be strikethrough (actually: “line-through”), which is probably better-suited for a print stylesheet..diff-addedline insWordPress color. Default text-decoration forinsis underline, which again might lend itself better to print..diff-contextThe WordPress admin diff shows all content for each post. Here, I’ve hidden the lines where there are no changes. Google, for one, frowns on hiding text, but since revision pages are marked as “noindex”, it shouldn’t hurt anything, other than wasting some bandwidth in sending down text that isn’t shown.
Other CSS
The note at the top uses <div class="revision-header"><p>. For example, I styled mine with:
.revision-header {
background-color: yellow;
border: 1px solid #3a8b8c;
padding: 10px; }
div.revision-header { padding: 0 10px; }
The revision list uses:
<div class="post-revisions"> <h4>Post Revisions:</h4> <ul class="post-revisions">
And the changes section:
<div id="revision-diffs"> <h4>Changes:</h4>
It uses an id instead of a class to allow the anchor jump “See below for differences.”
(The h4 headers for the list and the diffs can be changed in “manual mode”. Keep reading…)
Diffs / Changes
The revision comparison shows the underlying HTML in a table, with columns for previous and current revisions. With things like URLs, it’s likely you’ll have long strings that won’t wrap nicely in the table. The text will overflow to the right when this happens. In my theme, this means things will be hidden. Depending on how long your non-wrapping strings are, you can lose the entire right column. CSS will allow for a scrollbar in this situation:
#revision-diffs { overflow: auto; }
But to me, that’s not an ideal solution by itself. It doesn’t give you a nice side-by-side look at things. So what the plugin will do is try to break things up with spaces, inserting them in text that is at least 24 non-space characters long and has slashes, dashes, underscores, etcetera as breakpoints. This allows for better wrapping and doesn’t really change the gist of the comparison, IMO. Previous and current revisions will tend to break at the same spots and not be highlighted. If a diff is somehow introduced, it should be clear that it’s nothing significant. The revision text shown as the content is still the original text.
It’s still a good idea to use overflow auto in case some long strings don’t have breakpoints. Maybe you have narrow columns and tend to use words like internationalization or supercalifragilisticexpialidocious.
(If this feature offends you, you can modify the plugin code, taking out the calls to the prd_break_up_lines function.)
Automatic vs Manual Mode
In “automatic mode,” once you activate the plugin, revision information will show up on single post views (e.g. single.php) as shown in the screenshots. There is no need to modify theme files. (Other than your CSS, as discussed above!)
With “manual mode,” you can specify where in your theme you want revision info to be displayed. Most commonly, you’ll make calls from single.php to:
<?php the_revision_note_prd() ?> <?php the_revision_list_prd() ?> <?php the_revision_diffs_prd() ?>
Which I think are pretty self-explanatory. One of these will have to come before the_content so that when filters are applied on post content, the plugin will know it is in manual mode and won’t do the automatic stuff. To me it makes the most sense to have the note at the top as a warning for when a previous revision is displayed, which will take care of this requirement. (Even on current revision posts where there is no note, it will still set the manual flag.)
If you insist on putting all the function calls after the post content, you can place <?php prd_set_manual_mode() ?> before the_content is called in your theme.
Manual mode allows you to show revision info on “pages” (likely: page.php) in addition to single post views. (Or, if you want to do this in automatic mode and you’re willing to make a code change to the plugin, you can look for this line in the prd_display_post_revisions function: if (!is_single()) {, and change to: if (!is_single() && !is_page()) {.)
You can also put revision info on pages with multiple posts (e.g. the main index.php page or archive pages), although in those cases it only makes sense to show the revision list. When calling the_revision_list_prd() from within “the loop,” you’ll need to force an update of the revision info for each post by using the first optional parameter, $refreshGlobals:
the_revision_list_prd(true)
(When you call the three _prd functions, the first call will load all the revision info into a set of global variables. Without forcing the update with $refreshGlobals=true, you’d see the revision list for the first post for every following post displayed on the page.)
In manual mode, you can also specify your own header text for the revision list and diff sections. This is the second optional parameter for the list function:
the_revision_list_prd($refreshGlobals=false,
$header=REV_LIST_HEADER)
Where the default REV_LIST_HEADER is <h4>Revision List:</h4>
The header is the first and only optional parameter for the function:
the_revision_diffs_prd($header=REV_DIFFS_HEADER)
Where the default REV_DIFFS_HEADER is <h4>Changes:</h4>
An example of calling these from single.php:
<?php the_revision_list_prd
(false, '<h3>This is the revision list!</h3>') ?>
<?php the_revision_diffs_prd
('<p><b>These are the diffs!</b></p>') ?>
Download v0.7 (87K)
Also available from the official wordpress.org plugin page.
The plugin has been tested with WordPress 3.0 and is licensed with the GNU General Public License, version 2 or later.
Updates
23 August 2010: v0.7: Nicer diff styling using built-in wp_text_diff function. Requires CSS for the “nicer” part.
16 August 2010: v0.6: Manual mode lets you make function calls from your theme for control over where revision information appears.
2 August 2010: v0.5.2: Compares and reports on changes in post title.
1 August 2010: v0.5.1: Revision note at top of post changed to use div + p instead of just p.
Notes / Acknowledgments
- I don’t plan on using this right now on my site, so you’ll have to go to Scott’s Wordyard blog to see it in action. (Maybe not until a few days after this post.) And for more examples, please leave a note in the comments if you decide to try it!
- The default behavior of WordPress is to save all revisions, but can be modified to save only the most recent “N” revisions. If used for the “trust factor,” it would be best to save all revisions, don’t you think?
- The markup generated by the plugin validates as HTML5, and very possibly will also pass as Transitional XHTML 1.0.
- Let’s consider this to be experimental and proof-of-concepty, although so far it appears to be robust enough. I tried to take care with security checks so that only post-publication versions of public posts can be viewed. It seems that WordPress’s security mostly carries the day. If there are private posts, only those with access should be able to see revisions. However, caveat emptor. Please let me know if you find any problems, with security or otherwise.
- How cool is free software? I find that no matter how much I work with “free as in freedom” stuff, I still get a kick out of the way this works. We should all be free to build on each other’s work. It’s a culture of cooperation. Without the boost from the original, I likely wouldn’t have done this. (Thanks, D’Arcy!)
- I found a nice PHP implementation of the Unix “diff” utility written by Daniel Unterberger and Nils Knappmeier, PHPDiff, which I modified for use in earlier versions, but later started using the built-in WordPress function,
wp_text_diff. (Still, more wonderful free software at work.) - Thanks to Scott R. for starting the ball rolling. I enjoyed working on this little project and doing my part to save the credibility of journalism in the digital age.

9 Comments
Thanks for doing this! One question/suggestion I had: it looks a bit obtrusive at the bottom of the content. I’ve helped that with styling rules on my blog; but the theme I’m using puts the post’s publication date at the bottom of the content, and I’m thinking that ideally I’d be able to put the revision history underneath that instead of above that. (Which would, of course, require fiddling with the theme that I’m using.)
I looked at the implementation, and it wasn’t entirely obvious to me how to get that to work, unfortunately; I guess I’d want to remove all the content filter manipulation (including the manipulation within prd_display_post_revisions() itself), but in general I’d rather not use patched versions of plugins so I can avoid upgrade issues. (Plus, I’m not a WordPress hacker, so I’m not sure where the pitfalls are.)
Any suggestions here? Maybe add a configuration option to let me have the plugin installed but leaving out the the_content filter (I think the wp_head filter is good no matter what), and then break out separate header/footer functions that I can call from within a theme? Actually, reading through the code, maybe those functions are already there in the form of prd_get_revision_note() and prd_get_revision_list0 / prd_get_revision_diffs(), so maybe all I have to do is comment out one line of code and then call those functions from appropriate places in my theme – does that sound right? I’ll try to play around with it a bit more when I have some time.
Thanks again for the plugin, it’s a great idea.
10 August 2010 at 11:28 pm
You’re welcome, David. I’m glad you like it.
I had considered having an option to make separate calls from the theme for the three parts: revision note, revision list, and diffs. But we figured that could wait, for now, in favor of the simple drop-in approach.
I think there would still need to be some work done in the filter, when the current text is replaced with the revision. So the challenge is: how do we suppress the other filter stuff when someone is using these theme calls?
If you were to modify it, you wouldn’t have to worry about making that distinction. Remember that each call would need to do the checking of the “rev” URL parameter. (Making sure it’s a valid revision for that post and seeing if a revision is being displayed or not.)
I’ll think about it some more and maybe will have time to try some changes later in the week.
11 August 2010 at 5:57 am
(Update: this is done; will update this page and wordpress.org later…)
16 August 2010 at 5:59 am
Heya Scott!
Thanks for the great work – little questions though.
I want to have a visible revision box for my published pages. Is there a quick way to implement this from your plugin?
Gr.
Dimitri
16 August 2010 at 6:30 am
Hi, Dimitri. You’re welcome, and thanks for trying it out!
Yes! With the new “manual mode,” you can put function calls in
page.phpto have revisions there also. I’ll be updating the wordpress.org page tonight with this new version and documentation.16 August 2010 at 4:14 pm
Scott you are an ace! Thanks! How cool is free software indeed ;-)
18 August 2010 at 3:36 am
It’s also possible to have revisions on pages in “automatic” mode (no theme function calls) if you make a small change to the plugin:
if (!is_single()) { return $content; }Becomes:
if (!is_single() && !is_page()) { return $content; }18 August 2010 at 5:44 am
Thanks for the effort. Testing this out at my new multisite community for creative writers. I was looking for something that could expose revisions to unfinished projects so that the community could observe the creative process and see improvements and implementation of suggestions. So far looks to be absolutely perfect. Danke.
20 August 2010 at 10:09 pm
(For any comment subscribers: v0.7 now available using built-in WordPress diff which can be made to look much better with CSS…)
24 August 2010 at 5:32 pm