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!) There is also an option to show revision info on pages (e.g. page.php).
With “manual mode,” you can specify where in your theme you want revision info to be displayed. (Set this mode as an option on the admin page.)
Most commonly, you’ll make calls from single.php or page.php to:
<?php the_revision_note_prd() ?> <?php the_revision_list_prd() ?> <?php the_revision_diffs_prd() ?>
Which I think are pretty self-explanatory. (I think you’ll want the note above the content so that it will be immediately obvious when someone is viewing a revision.)
Previous to version 0.8, there was the function <?php prd_set_manual_mode() ?>, to be used in case none of the calls came before the content, but this has been deprecated now that there is a manual mode checkbox option. This function doesn’t do anything anymore and will likely go away in a future version.
With manual mode, you can 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 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 info for the first post on each of the following posts displayed on the page.
Previous to version 0.8, there were parameters for specifying optional list and diffs headers by way of the function calls. This has now been added to the admin options page and works for both automatic and manual modes. The optional parameters are still there, but they don’t do anything and are deprecated.
Admin Options
WordPress Admin » Settings » Post Revision Display
- Show revisions on single posts. (default = true / checked)
- Show revisions on pages. (default = false / unchecked)
- Hide the message that appears if there are no post-publication revisions. (default = false / unchecked) So, if this option is set, you won’t see the message “Post Revisions: This post has not been revised since publication.”
- Revision list header: (default = <h4>Post Revisions</h4>)
- Revision diffs header: (default = <h4>Changes</h4>)
- Manual Mode. (default = false / unchecked)
When the plugin is first installed, or when it’s deactivated and re-activated before setting the options, it will have certain defaults that correspond to how automatic mode worked in versions previous to 0.8. If you’re upgrading from an older version, you should check your options to make sure they make sense.
Internationalization (i18n)
With version 0.9, the plugin is ready for translation and has Spanish language files. (Thanks to Fran Ontanaya! contacto at franontanaya dot com) I’ll be happy to add others.
Download v0.9 (110K)
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
9 December 2010: v0.9: Internationalization support added, with Spanish language files. Language support assumes plugin is in plugins/post-revision-display sub-directory, so you may have to reactivate your plugin and delete the old file if you’ve been keeping it in the plugins root dir.
19 November 2010: v0.8.1: Fixes loophole in automatic mode where revision info appears outside of single post and page views when the_content is called. Renames a class output by the built-in WordPress function from “content” to “diff-content” to avoid clashing with user themes.
14 November 2010: v0.8: Now has options available via the WordPress admin settings menu. (When upgrading, be sure to review this page and the options, since defaults may not carry over, and some behavior changes!) Fixes bug where revision links wouldn’t work if pretty permalinks turned off.
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. 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.


44 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
Thanks for writing this plugin. One feature that might be useful would be to indicate the revision that a commenter was commenting on in their comment. For example, people often comment to point out that a link doesn’t work and then the blogger fixes it so the comment ends up seeming incorrect. If each comment said something like “this comment was made on revX of this post” somewhere then this might be less confusing.
6 October 2010 at 1:11 pm
Hi, Matt. I agree that would be useful/interesting, although it would widen the scope quite a bit. Right now we’re just exposing the revisions that are there. To make the link with the comment, it would require storing something new in the database, or at a minimum maybe hooking in to the comment posting to add to the comment text itself at the time of posting.
6 October 2010 at 3:44 pm
Hi there, I have a general WordPress question you might be able to answer: WordPress allows turning off revisions or limiting to a certain number.
How about allowing revisions for posts but not for pages? How about allowing revisions only for a certain custom post type?
Is anything like that possible?
7 November 2010 at 1:21 pm
Any chance you can make it compatible with this syntax highlighter: http://wordpress.org/extend/plugins/syntaxhighlighter/
Here is an example of what I would like to achieve: http://pacura.ru/code/nginx-conf/ kind of a pastebin clone :-)
7 November 2010 at 1:36 pm
Hi, ovidiu — Thanks for trying out the plugin.
for your first question, I don’t know about options for specifying revisions for posts but not pages, or other kinds of revision customizations.
For your second, I’m not sure what you mean about making it compatible with the syntax highlighter.
7 November 2010 at 3:03 pm
well, what I meant with compatibility, check out my example.
the diff tables look simply ugly and empty?
is it me making mistakes there?
for a starter I copied your css examples…
7 November 2010 at 3:07 pm
just realized: it was me being silly, didn’t scroll all to the right. works, kinda, css broken for me :-( let me know if you have an idea how to fix it otherwise I’ll give it a go tomorrow :-)
thanks for the really cool plugin!
7 November 2010 at 3:10 pm
It should look better than that. I wonder if something is not quite right with the CSS?
It should look more like the diffs at the bottom of this page:
http://www.wordyard.com/2010/10/24/when-campaign-spending-is-anonymous-reality-gets-slippery/?rev=3011
7 November 2010 at 3:41 pm
hmm… here is the css I copied and scraped from this site, am I missing anything? => http://pacura.ru/code/css-for-the-post-revision-display-plugin/
7 November 2010 at 4:10 pm
would you mind changing or at least considering the CSS classes you use? I am getting into trouble as .content is already in use in my template, needs heavy changing of css to get the diffs looking right :-( and I think most themes use content for the main content…
15 November 2010 at 3:02 am
The plugin doesn’t use any classes named “.content.”
I think all of the related classes are listed in this post. There are a few from the plugin for display on a page, a couple for the admin page, and several from the built-in diff function, but none named content that I can see.
15 November 2010 at 5:12 am
well it definitely has classes labeled as content on my site and on the one you gave as an example above: scot wordyard#s blog… this I copied from his source:
`
Changes:
10 November, 2010 @ 8:05Current Revision
Content
<a href=”http:// http://www.wordyard.com/wp-content/ uploads/2010/ 11/WSJ-screen- shot1.png”><img …..`
I h´just cot the part with col class=”conten” out its not the complete sourcecode I cited here, please have a look…
15 November 2010 at 9:55 am
ok, it looks my html was clipped out. what I was saying is that the example you linked to, i.e. this one: http://www.wordyard.com/2010/11/10/wall-street-journal-pushes-trumped-up-obama-shakeup-story-stonewalls-questions/?rev=3105 has a col with a class of `content`
15 November 2010 at 9:57 am
Ah — I see! But unfortunately, that comes from the built-in WordPress diff function, and I don’t know of a way to change that. (Other than changing *that* function, which I don’t think is advisable.)
I notice on Scott’s page, as on mine, our themes are using “content” as an id rather than a class, which explains why we haven’t seen it as an issue. Maybe that can work for you also?
15 November 2010 at 11:51 am
working on it :-( I’d point you to the discussion but I fear its a paid forum and you might not see all the posts but I can give it a try: http://themehybrid.com/support/topic/got-a-little-css-problem
16 November 2010 at 6:50 am
Hi, ovidiu — one solution that occurs to me is we can simply do a find and replace on the output of the diff function, to rename the col class. (Maybe using something like
prd-diff-content.)That shouldn’t be hard to do and I may have some time this evening.
16 November 2010 at 7:25 am
awesome. I was without internet for the past two days. Just cut down a tree in the backyard that was impacting my internet :-)
ready to go now!
18 November 2010 at 1:22 am
This plugin is exactly what I need. Thank you very much. I do however have one issue and need to know if this is expected behaviour.
It works as described for the admin user on the site. But if a contributor or editor views a post, the always says “There are no revisions for this post”, even if there are. The admin user can look at the same post and it shows all revsion info as expected.
Can you advise?
Thanks
Liz
18 November 2010 at 8:23 am
Hi, ovidiu — it’s a small change to make but I haven’t had time to work on it the past couple of nights. (I do have regex for the search and replace worked out.) If not tonight, then I’ll certainly have time this weekend. I have to bundle a small fix in there also for something else.
Liz: Something’s not right. Are there “post publication” revisions? Although if not, the admin user should only see post-publication revisions as well so should also see the message about no revisions. When you say the admin user can see all revisions, do you mean on the displayed page, or in the WP admin editing page?
18 November 2010 at 11:01 am
Hi Scott,
Really like the pluggin.
Is there anyway this could be dropped into a widget? Then it would make it really easy for me to control where and on what pages its displayed.
Thanks, Steve
26 November 2010 at 9:11 am
Thanks, Steve. I have very little experience with widgets — what do you have in mind that the widget would do that the automatic mode doesn’t handle today? Do you want greater control over where elements are displayed, as the manual mode allows? How would you recommend the widget would do that, if so?
26 November 2010 at 10:27 am
Hi
Great plugin, thanks! I’m having problems with the “Hide the message that appears if there are no post-publication revisions.” option. Although checked all pages/posts created before installing your plugin without revisions show the “Post Revisions: There are no revisions for this post.” message. When I create a new page/post (after installing plugin) it works. You happen to know why? Cheers, Miki
18 February 2011 at 2:45 am
Follow up on the comment above. It would be great to be able to set the ability to post revisions for specific pages or even better the other way round to be able to block posting revisions on a per page basis. If you give me a hint how I could do this then I might be able to make the change to the code. Thanks a million!
18 February 2011 at 4:00 am
Hi, Miki. For your first question, I don’t know. I know at least one person had some issues with very old posts, but in general, it seems to work okay on pre-existing posts. So there must be something about those posts, but I have no idea what it might be.
For your second question, It seems you could add a place on the admin page to specify posts to include or not include, and then in this function:
prd_display_post_revisions($content)You would check against your list and take action accordingly.
(I don’t know that I’d want to include this feature in my version, but of course feel free to go to town and have fun with it!)
18 February 2011 at 9:03 pm
Hi there,
Great plugin!
I’m currently using it to create a sort of wiki-based online essay that a group can edit and then view the amendments that have been made, but I’m having a little trouble with one thing.
I’d quite like to be able to see links and images in the diffs section rather than the HTML for them; is this possible?
Many thanks!
Ralph
25 April 2011 at 1:58 pm
Hi, Ralph. I’m glad you like it. The built-in diff function returns it like that by default. I don’t know what other options there may be. (It seems best to me to see the HTML, since the purpose of the diff is to compare. If you were looking at links, for example, you wouldn’t be able to easily see if the target had changed.)
25 April 2011 at 6:00 pm
Nice plugin, great work! Is there a way of turning off the author name display next to each revision in the list? I don’t need it on a single author blog.
27 June 2011 at 7:22 am
Hi, Matt. That part of the code is from the original version by D’Arcy Norman and I’ve always been a bit hazy on how the $titlef assignment (currently on line 254) works with the sprintf function on line 292. But that’s where you’d make a change for this. You could probably comment out the $titlef, $name, and $title assignments and just change one line:
to:
I think that it would retain the [Current Revision] note on the first item in the list.
27 June 2011 at 7:50 am
Cool, great thanks for the swift reply — I just changed it to print the date only, works great :-)
27 June 2011 at 8:11 am
I realise this is an older plugin, but it’s one I’d like to be able to make use of. As it functions at the moment however, every time I save a draft and preview a post it creates a revision, which quickly starts to junk up the list.
Is there any way I can prevent this plugin from creating revisions, at least until I have made the post public?
20 April 2012 at 7:03 pm
Hi, Geoff — the plugin has nothing to do with how WordPress creates and manages revisions. It only provides a view to what is there.
But it should only show revisions made after a post is published. Are you publishing posts privately somehow and then making them public later? I haven’t experimented with scenarios like that.
22 April 2012 at 8:10 pm
Thanks for the reply Scott — sorry I didn’t see it sooner.
I just tested it again, and I see where I got confused. As I write a new post, the preview does in fact show the different drafts. However, when I publish the post, those changes are not revealed.
That’s a big relief – I’ll be sure to give this plugin another try. :)
Another suggestion though: It’d be useful to have a custom field to add a note about the revision, as with Wikipedia. (This would be doubly useful for explaining what changes were made to metadata).
Thanks again!
26 April 2012 at 11:17 am
Have you considered implementing the Memento architecture in this plugin? http://www.mementoweb.org/guide/quick-intro/ . That would allow users with the right browser plugin to request the version of a page that was active at a given date and time. It’s a worthwhile project, and it would be great to see support for it in a WordPress plugin. I think you’ve already done the hard part by figuring out how to extract a time-stamped list of post-publication versions, and the rest is just detecting and executing the Accept-Datetime value in the http header of a request.
13 September 2012 at 10:22 am
Hi, Peter. I wasn’t familiar with that, but it’s interesting to learn about it, and it sounds cool. I like the idea of being able to better preserve and access the history of things on the web.
I’m not looking to do any development right now on the plugin, but would be happy to add a developer to the wordpress.org project to carry on the work, if someone wants to take it up.
13 September 2012 at 1:36 pm
Thanks, Scott. I think I’ll propose it as a project for the hackfest at Access 2012 in Montreal in a few weeks: http://accessconference.ca/2012/09/12/access-2012-hackfest-lets-get-started/ . A bunch of library techies might well be interested, since preserving web content is a hot topic in the digital library world now. If something comes of it, I’ll let you know.
13 September 2012 at 7:14 pm