WordPress Core Contributor

Monthly Archives: November 2012

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).

This is a roadblock standing in the way of automatic WordPress upgrades. While WordPress is getting smarter about automatically deactivating plugins that generate PHP errors during activation, it is still impossible to tell if any single plugin is going to break after core has been upgraded (particularly with Javascript-heavy plugins, note the libraries mentioned above). Hosting providers like the one I work for (Bluehost) are very concerned about pushing WordPress upgrades automatically if there’s a significantly high chance it will break the customer’s website. The numbers are hard to calculate since the chances that something will break rise depending on the number of plugins installed. Currently though, it’s roughly 4% to 8% per plugin (4% if upgrading a single WordPress release like 3.3 to 3.4, and about 8% if upgrading from 2.8 to 3.4).

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 truth is, even though WordPress still includes API deprecated all the way back to version 1.5, a quality plugin or theme written that long ago simply will not work with WordPress 3.4 unless it only ever tied into one or two hooks, only called a few core methods, and never touched any Javascript libraries. Neither will a plugin written for WordPress 2.5.

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.

Remaining Issues

Chrome only provides one single Javascript API that can be easily versioned, it doesn’t include any 3rd party Javascript libraries. WordPress can’t version any 3rd party libraries in the same way, nor can it provide two different versions during the transition period where two manifest versions are supported. We will still see issues while updating 3rd party libraries, however, we will at least have a better method of timing those 3rd party library updates so they break the least number of plugins and themes as possible.