As a core contributor on WordPress for a while now, one of the biggest problems I’ve found is that WordPress has failed to implement a realistic public API versioning model that could be helping plugin and theme authors, core developers, and users alike.
I want to get the discussion going on a new model that helps everyone, and I would like to get your input and support on bringing this major policy change into WordPress core. I’ve briefly discussed this with a very small set of plugin and theme authors already, and have come up with a solution I think everyone can get behind, but it still needs to be polished up, so I’m expanding the discussion to a larger audience for further input.
Where are we at right now?
The current WordPress API policies regarding deprecation and backwards compatibility is simple: “No public API is ever removed.” We do add deprecation notices to old methods that have been replaced with new API, but deprecated methods are never removed.
This results in the following issues I would specifically like to address:
- Outdated plugins and themes can never be removed from the WP.org plugin and theme repositories. When do plugins and themes die? The current policy says everything should still work, therefore, nothing should ever be removed. We know this doesn’t happen in practice though, and it’s the main reason we see big, bright warnings on items not updated within the last 2 years. Forget about finding quality plugins, this makes it difficult for users to find working plugins and themes in the repositories. According to plugin compatibility votes, 1 out of every 5 plugins in the WP.org repository is broken in the latest version of WordPress (consistently for the last 3 years).
- This policy is incompatible with every 3rd party library that is included with WordPress core. If we were to strictly adhere to this policy with 3rd party libraries, WordPress would be forced to never update any of the following libraries after initially adding them (or only updating minor releases within the same stable branch that was first included): jQuery, jQuery UI, TinyMCE, SimplePie, PHPMailer, POP3 (SquirrelMail), PemFTP, Plupload, Backbone, Underscore, and others. Many authors have seen their plugins and themes break when one of these libraries are updated in core anyway, despite the current backwards compatibility policy. We saw core break recently while updating SimplePie from 1.2 to 1.3 (during 3.5 development).
- This is one of the biggest contributors to the project’s technical debt. New features and infrastructure changes to WordPress core are limited to designs that remain compatible with WordPress versions as old as 1.0. This limits changes that desperately need to be done such as replacing the DOING_AJAX constant that makes unit testing WordPress incredibly difficult. We know it needs to happen, but it simply can’t be done because several plugins rely on this constant. It also means that the core WordPress code base is still littered with super rarely used code which, without a change in policy, is required to remain intact and maintained for decades to come (until someone arbitrarily decides on some random WordPress version to remove it in order to make way for a new feature).
You might notice that a couple of the issues mentioned are only actually problems because despite the current compatibility policy, in order for WordPress to move forward, it has to break some compatibility. It’s unreasonable to expect WordPress to stick with TinyMCE 2.1 and jQuery 1.1 that was included in WordPress 2.2. It’s also unreasonable to expect that every feature ever added to WordPress core remains in core, such as the Links Manager being removed between 3.5 and 3.6 or the PHP-Gettext library that was removed in 2.9. Smaller backwards incompatible changes can even be found like this.
The Versioned API Approach
When discussing automatic updates, Matt has often referred to the future of WordPress working in a very similar fashion to Google Chrome. Users shouldn’t need to know or care what version of WordPress they have installed. This should also be the case when installing plugins and themes, so when we look at how we can turn the plugin repository into a version-free world like the Chrome Web Store, we have to look at how they handle these issues with Chrome extensions and apps.
Chrome extensions are all required to specify a manifest version that dictates which extension APIs that version of the extension uses. Any deprecated extension APIs are tied to the current manifest version, and are slowly phased out and removed entirely according to a lengthy schedule (a period of about two years) spanning several Chrome releases. Once a manifest version is officially deprecated, nothing changes for a period of about a year. Then the Chrome Web Store starts blocking new extension submissions for a few months, then it starts blocking updates to extensions using the deprecated manifest version. A few months later, old extensions are filtered out of search results, the wall, and category listings (just like how WordPress plugins more than 2 years old are filtered). Developers of those extensions are notified about removal from the Web Store at the same time, which will happen a few months after those notifications. Another few months after that is finally when the next release of Chrome will automatically deactivate any deprecated manifest version extensions and remove all API tied to that version.
If we were to apply the same policy to WordPress plugins and themes, here’s how such a schedule might look like for the WP.org repositories (dates are estimates based on three month release cycles):
January 2013 (before WordPress 3.6)
- API deprecated before WordPress 3.5 is marked for manifest version 1 compatibility, anything deprecated after is marked for manifest version 2 compatibility.
- Documentation should be updated for “Writing a Plugin / Theme” on new requirement to indicate manifest version, and noting manifest version on all deprecated API docs.
WordPress 3.8 (September 2013)
- Extend blocks all new manifest version 1 submissions (plugins and themes). All items with unspecified manifest version are assumed to be version 1. This forces all new items to use manifest version 2.
WordPress 3.9 (December 2013)
- Extend blocks updates to existing plugins and themes if manifest version 1.
WordPress 4.0 (March 2014)
- Extend no longer lists manifest version 1 plugins and themes on any search or browse page, but leaves items listed (only accessible by bookmark, or external links).
- Notice emails are sent to all authors with manifest version 1 items informing of removal from Extend within 3 to 4 months if they are not updated.
WordPress 4.1 (June 2014)
- Version 1 plugins and themes are removed from Extend.
WordPress 4.2 (September 2014)
- WordPress core will auto-deactivate manifest version 1 plugins and themes (potentially falling back to the default bundled theme). Version 1 items refuse to activate, but files are left installed.
Note that while this schedule outlines WordPress release versions, only the last step in this schedule is required to be tied to an actual WordPress release. Every step before it can be extended to any date if it looks like authors are having trouble getting plugins updated.