I am, like everyone else it seems, on the hunt for a solution to the Content Syncing Problem. If Alice and Bob are each working locally on their dev sites, creating and editing content, and meanwhile the client is doing the same on live, how can everyone’s changes be deployed without anything being overwitten (and without Alice and Bob simply repeating their GUI actions on live?)
My research so far has turned up a few attempts to version the entire database – such as VersionPress and MergeBot, both of which are no longer maintained, and WPMerge, which is quite expensive at c.$100 per site. Which means $10,000 if your company maintains 100 WP sites…
That’s because it’s a hard problem. Getting dev into the same state as live is easy enough – just replace the whole dev database with the one from live (anonymised & url-replaced). But the other way is difficult because we don’t want Alice or Bob’s changes to overwrite the client’s, or indeed each others’.
I think I may have found a way to solve this, not for the whole database, but just the pages, posts, menus, custom fields – things that are likely to change regularly, and take a lot of work, and would therefore benefit the most from a more streamlined workflow (unlike, say, plugin configuration and settings options, which change less often & take less work to apply, so could just be re-done manually).
Advanced Custom Fields Pro has the Local JSON option which stores custom field metadata as json, so that part of the problem is solved.
For posts and pages (and menu items, which can be added as a custom endpoint), could the WP JSON API could be used, I wonder, in something like the the following way?
A plugin which, when configured for the dev site, hooks into the process of the developer creating, updating or deleting entities via the GUI, and generates files with names like update_post_<slug>
or create_menu_<slug>
, containing the relevant JSON data. These can then be committed to git, and when pushed to master, automated deployment would take care of doing the API calls on live, replaying the changes. The plugin would provide support for that.
If this worked it would avoid the overwriting issues that you get when just deploying the whole database from dev to live.
Suppose Alice is adding a new menu locally, and whilst she does so, Bob is adding a post, locally, elsewhere. The client, meanwhile, is editing the content on the home page. If Bob and Alice both get SQL dumps from live at 10am, then do their work, if Bob finishes at 10:30 and "syncs" his local database to live by simply overwriting it, the client’s work for the last half hour will be lost. And if Alice then does her "syncing" at 10:31, Bob’s work will be blown away, too.
Whereas with this as-yet-fictional plugin, Bob’s post being added would generate an API call to create the post, and when pushed to live it would not overwrite anything but just add the post to whatever is there. And then Alice’s change would create the menu, and not overwrite anything either.
It wouldn’t solve the problem of the specific type of merge conflict that would occur if multiple people were editing the same piece of content at the same time. But neither does WPMerge, nor indeed the web editor! So I don’t think that’s too bad.
There’d be an issue if people created multiple posts with the same slug. But presumably the API POST
calls would fail, and the CI server could detect the error and fail the build. Then there would need to be some manual interaction. But it is unlikely to be a common occurrence.
This seems to me like it could work and would not be terribly hard to write. But I think there must be something I’m missing, because if it was really that easy I’m sure it would have been done already (and I hope it has, but if so I haven’t found it!). So I would be keen to hear what you think the catch might be, before I waste any time trying to write it…