Arming WordPress for a post-truth era
How we developed plugins to improve collaborative editing and editorial accountability for citizen journalism at WikiTribune.
As journalism fights both ideological and economic battles, WikiTribune is exploring a new premise: is it possible to combine a traditional newsroom’s rigour and methods with the more extensive and far-seeing human resources of the crowd, creating a new kind of editorial community which naturally selects facts and evidence, and works together, in the open, to eliminate lies, misinformation, bias and error?
We first met WikiTribune in the summer of 2017. They had journalists, they had subscribers, and they had a beta version of the website, built in WordPress, but they couldn’t yet open up to community participation, because the core platform lacked two critical pieces of functionality:
1. Allow multiple users to edit the same post at the same time.
Normally in WordPress, when Alice starts editing a post, other users are locked out; if Bob wants to edit it, he can either a) wait, or b) take over.
WikiTribune wanted members of the community to be able to edit independently, without pressure or friction from other users, especially on top news stories that might attract a lot of interest.
2. Allow editors to moderate / approve / reject changes to articles.
In WordPress, once a post is public, all subsequent updates are automatically public too.
WikiTribune staff needed community-suggested edits held in an approval queue, so trolling and vandalism could be kept in check.
At Yes We Work, we had already done a lot of work customising WordPress for editorial websites, and we’d released a WordPress Dashboard plugin to help multi-author teams keep track of the content of complex sites. We were excited to be asked to tackle both tasks for WikiTribune.
The result is two open-source plugins, which work both together and independently: Fabrica Collaborative Editing and Fabrica Pending Revisions.
1. Fabrica Collaborative Editing enables simultaneous editing by multiple users of any WordPress Post, Page or Custom Post Type.
WordPress’s native ‘single user lock’ is practical for small teams where people know, trust and can talk to each other, but would create a lot of friction and frustration on an open platform like WikiTribune that aims to have thousands of contributors working independently to improve urgent news stories.
We discussed several alternative approaches to simultaneous editing:
- Google Docs’ real-time collaboration works best for a small number of trusted users, but is chaotic and distracting when more than a few editors are working on the same section. It also poses huge problems for editorial accountability: since multiple users can edit the same word, phrase or sentence, it’s complicated to attribute changes in meaning to specific users. It was also felt that authors (especially those who do not know each other) would prefer to write in relative calm, without others trampling through their half-finished sentences.
- Version control systems (eg. Github) allow documents to be checked out by multiple users for independent editing. Although closer to what WikiTribune needed, these systems also permit ‘forking’, (parallel revisions can be kept separate indefinitely), but WikiTribune aims to maintain and constantly improve a single version of a news article.
- Wiki(pedia) has multi-user check-out, and independent editing, but avoids forking by enabling users to manually merge their changes with any other edits that have been made, so branches only exist for as long as a user is editing. It was felt (particularly by Jimmy Wales) that this was the most appropriate model for WikiTribune too.
Fabrica Collaborative Editing implements this Wiki-like functionality.
Key features and functionality
- Overriding WordPress’s single-user lock which prevents multiple users from editing the same post at the same time. This involves a combination of delicately modifying (Heartbeat API) transmissions between client and server, to stop the lock mechanism being triggered but without interrupting other functionality like autosave, and hooking into some UI filters to disable warnings elsewhere.
- With the lock disabled, users could continually overwrite each other’s changes, so to prevent this, we intercept save to check whether other user(s) have suggested changes since the current user started editing.
- If there are other changes causing edit conflicts, we cache the current user’s changes (with the Transients API), abort the regular save operation, and present a conflict-resolution interface.
- The conflict resolution interface shows comparisons (diffs) of all the conflicting fields (title, body, textual Advanced Custom Fields) highlighting the differences. For this we use the standard revision diffs in WordPress, but we additionally implemented Visual diffs where stylistic HTML features are rendered as they would be on the front-end — essential for writers who don’t understand HTML to be able to evaluate differences, and to make it much easier to check changes in elements like images.
- Revising the conflicts, users then edit their version to take into account the other users’, then save again. If there have been yet more edits, conflict resolution will kick in again; if not, the changes are committed and a new revision is created.
- We also provide a simple mechanism for users to abandon their edit in case they consider the other user’s changes to be more suitable than their suggestion.
- Collaborative editing can be enabled or disabled per (custom) post type (via the plugin’s settings screen).
Roadmap (see Github project)
- Live notifications of simultaneous activity by other users (eg. “5 other users are currently editing this post” or “Another user has suggested an edit; would you like to merge your changes now?”).
- Meaningful diffs of non-textual fields (for example, taxonomies or featured images) and other improvements to visual diffing.
- Per-paragraph or per-change conflict resolution, which might allow for both:
a) automatic merging of revisions if edits are in different sections of the article;
b) faster merging by permitting users to simply “accept / reject” each smaller change, with the current manual edit option only needed in subtler cases.
- Gutenberg compatibility.
2. Fabrica Pending Revisions allows edits of Posts, Pages and CPTs to be held in draft mode and approved by editors before publication. It also adds revision tracking for additional fields, and improves the ‘compare revisions’ interface.
On a one-person blog, most of the time, once you’ve published an article you’ll want any subsequent changes or corrections to go live as soon as you make them. But on a multi-user site where there’s a difference between what contributors, authors and editors are trusted to do, more accountability and control over the different phases of publication are essential.
WordPress’s only native mechanism for moderation is the basic draft mode, which applies before initial publication and obliges non-editors to ‘submit for review’ rather than being able to publish directly.
This didn’t cover all of WikiTribune’s requirements for published pieces, which have to remain public and open for editing by all, but with community-suggested changes withheld from publication until they are specifically approved, not only for legal reasons but also because, with its mission including an assault on fake news, it is vital that non-facts do not get into the wild.
WordPress’s native revisioning system, which adds a new entry to the posts table for each revision submitted, and records its author, at least provides a solid foundation for the model of accountability that WikiTribune needed to implement. But we had to extend this basic functionality to allow editors to determine which revision in an article’s timeline is the public one at any given moment, while still allowing the community to edit collaboratively as described above.
The result is the Fabrica Pending Revisions plugin.
Key features and functionality
- Each post’s ‘accepted revision’ ID is tracked (in a hidden custom metafield).
- As well as a post’s title and content, we add hooks to track taxonomies (categories, tags) and featured images per revision so that changes to these fields are also subject to moderation. (By default WordPress does not track them along with revisions, they are committed straight to the main post.) For metadata / custom fields, we currently assume the use of Advanced Custom Fields, which already tracks its fields along with revisions.
- The publish / save button display logic is modified such that:
a) Non-editors can only ‘Suggest edit’, creating a revision that goes into the moderation queue;
b) Editors can both ‘Save pending’, which creates a revision that’s not yet published and ‘Update’, which will make the current edit public by setting the post’s accepted revision.
- On the front-end, template tags are intercepted so that the accepted revision’s content is shown (everything including title, body, excerpt, taxonomies, featured images, ACF is hooked) — rather than the parent post object’s, as this contains the latest version, which may not yet have been approved.
- The revisions timeline is enhanced to indicate:
a) The currently approved revision;
b) The subsequent revisions (which have not yet been approved);
c) Metadata about each revision, such as its author, and which revision it was originally based on;
d) Per-revision actions including ‘Edit’(allowing users to use an older revision as the basis of a new edit, in case the latest revision has been vandalised; ‘Preview’ (which shows how the selected revision looks in the front-end, to allow for an in-context review of suggested changes); and for editors only, ‘Publish’, which allows them to select this revision as the currently accepted one.
- The editing mode can be decided per post type (in the plugin’s settings screen): the options are:
a) ‘Open’ (all changes are published immediately);
b) ‘Requires approval’, meaning changes by non-editors must be moderated;
c) ‘Locked’, which means only editors can edit.
- Additionally, the editing mode can be overridden per post, to allow particular stories to be locked temporarily in exceptional circumstances, or conversely, to allow certain stories to be completely open even if the default is ‘requires approval’.
Roadmap (see Github project)
- Gutenberg compatibility.
- Support tracking custom fields without ACF.
- Front-end display of revision timelines, chronology of contributions, moderation history, etc.
We hope journalistic and editorial organisations, and indeed other types of collaboratively-managed projects, will benefit from the functionality offered by these two plugins, and we look forward to feedback on them, and to seeing how the community takes them forward.
Some ways you can help:
- Leave comments, or email us (firstname.lastname@example.org) your questions or feedback.
- Star or follow the plugins’ Github repositories to keep up with developments.
- Test them on your own projects.
- File bugs, suggestions or pull requests.