WordPress Plugin and Theme API Manifest Versioning

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:

  1. 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).
  2. 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).
  3. 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).
  4. 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.

About these ads

20 thoughts on “WordPress Plugin and Theme API Manifest Versioning

  1. Pippin Williamson

    Overall I think I completely agree with most of what you’re arguing for, though I simply haven’t thought about it in depth for long enough to argue too strongly one way or the other. One thing I would point out: it is NOT impossible to remove plugins / themes from .org, they just don’t get removed automatically. Authors can request a plugin/theme removed (closed) at any time and reviewers can also close a plugin or theme at any time if needed.

    Reply
    1. Bryan Petty Post author

      Yes, it’s certainly possible to still manually remove items from the repositories, however, there’s approximately 4,400 broken plugins (out of 22,000) currently in the WP.org repository that should be removed assuming we went this direction. I don’t think that re-focusing the limited amount of time and resources that the plugin review team has to reviewing these 4,400 least used, and oldest plugins in the repositories is a good idea. They should be keeping an eye on updates to the most used plugins and reviewing brand new submissions.

      I just don’t see how we could manage this on a per plugin basis by hand. Even if we could, it would end up being very subjective rules based on each plugin reviewer as to what stays and what goes, which means one more political front that plugin and theme authors will have to put up with (i.e. how broken does the theme have to be? what qualifies as broken?). This is one of the reasons why nothing is removed unless specifically requested right now.

      Using the manifest version puts up a very clear, single line policy that no-one can argue with. Everyone knows exactly what needs to be done to keep a plugin or theme updated to stay in the repository.

      Reply
  2. Corey

    What if I find a broken plugin on WordPress.org and fix it? You are removing that possibility. Perhaps instead of removing items from search results, a directory of broken plugins could be made available for people that need the functionality and are willing to fix or pay someone to code a fix.

    Reply
  3. Bryan Petty Post author

    I think that more importantly, the WP.org repos are not there for archiving broken plugins that need fixed. That really would only be useful for maybe a handful of plugin developers (that like the idea of adopting abandoned code), but not anyone else, and even hurtful to regular users, who are the primary audience for the repos. This deprecation policy would ensure that the plugins removed are typically between 2 to 4 years old (depending on the time of the cycle), and if no-one showed interest in jumping in to help update it by that point (especially at 4 years old), the reason why is either because there was no interest in it anymore, or it was coded poorly to begin with, since the next developer decided to start a new plugin from scratch instead, and everyone is now using that.

    I’m not saying it doesn’t happen. In fact, the single plugin I have in the repo right now is one that was more than 2 years out-dated when I took it over, but at the same time, I did in fact end up rewriting it completely from scratch. The only reason for taking over the plugin was actually just because it was for the same purpose with the same goals, and there were potentially hundreds of people with the broken version of it installed (and yes, it was broken) that my update would fix. That wouldn’t be necessary with this policy though since the broken plugin will be automatically deactivated in everyone’s installation as long as there isn’t another update.

    Reply
  4. Kevinjohn Gallagher

    I love posts like this :)

    It’s funny though because I completely agree with the premise and the data presented, but not with the outcome. Here’s why: We developers believe that upgrades are both positive and (effectively) mandatory. The question being, why wouldn’t you upgrade?

    Thats simply not where human kind is though, and we’ve thousands of years of data to back this up. People like to use what they are already using, and before any change can happen, a net positive Return on Investment needs to be visible.

    For every time I here someone tell me of a wonderful WP upgrade story, I hear of 2 people who’ve had a nightmare upgrade. Of course the same is true for other software, and not just WP.

    (Chrome incidentally is in a very unique position, and shouldn’t be the benchmark, because it has only 4 buttons from a user perspective, and has no UI to update. “auto update” by WP can’t happen in a world where we randomly change the menu to “hover only”, or make it impossible to log out of the admin section for 13 months if you’re a keyboard user)

    I know many developers, or geeks in general, don’t agree with that premise; so at #wpcs i asked almost everyone I spoke to if they were running WP3.4, of course almost everyone was. I then asked them if they were running PHP5.4.4 (incidentally released 2 hours BEFORE WP3.4)… I only met 2 people that were out of (circa) 100.

    WP has an incredibly fast release cycle in terms of CMS’. That’s great if you’re in a position to take advantage of that, but not everyone is, nor wants to. So we have to approach this discussion from a view point that:

    1. Not everyone is on the latest version of WP
    2. The % of people on older versions of WP is only going to go up.

    Now at a certain point in time, either the % of people on version of WP, or a certain amount of time has past means that we can fully deprecate some old code. I’m all for that, i really am, but I fear that we need to do this in a managed way that will eventually fall to one of two extremes:

    1. Never deprecate
    2. Support the latest version only (zomg y u no upgrade)
    e.g. http://kevinjohngallagher.com/2011/09/omg-wtf-y-u-no-upgrade-kktnx/

    This becomes even more of an issue as we integrate not only just-released external libraries into the WP releases, but now that we’re adding pre-release alphas of jQuery into WP Beta’s, it becomes a living nightmare to debug where issues have come from (is it from the jQ upgrade, the WP upgrade, our theme, our framework, our browser, other plugins, or something else…).

    I think the points you raise are valid, and exceptionally well constructed. I think 100% backward compatibility is an amazing idea, and the fact that the core devs have managed it for so long is truly remarkable. But I think going forward, and I mean this across all of the WP decisions, we need to start being pragmatic and transparent, with a clear roadmap of when actions will occur and what their impact wil be.

    I’ve said it for years, and been more unpopular every time I say it: WordPress has some of the most amazing developers I’ve ever met working on it, but has far less non-developer-management than any other successful open source project. We need to accept and embrace the different attributes each of those skill-sets bring us, and plan accordingly.

    I think this is a great first step to an incredibly useful discussion, and I hope it’s not developer only, because sometimes we struggle to see the wood for the trees.

    Reply
    1. Bryan Petty Post author

      Thanks Kevinjohn, this is exactly the kind of stuff that needs to be discussed with proposals like this.

      It sounds like you’re mostly arguing against the idea of performing automatic updates to WordPress core. I know exactly where you’re coming from, and I mostly agree that in it’s current state, and with the current policies, we shouldn’t be pushing automatic upgrades to WordPress. As mentioned, there is a large percentage of WordPress installations that break after upgrades currently, and in reference to automatic updates, anything above even 2% is considered a large percentage. I don’t have stats on that, but my general impression is that we might be well above 10%. That’s incredibly scary, especially where my company hosts 5 to 10 million WordPress installations.

      However, this is because WordPress *needs* to break compatibility somewhere at some point, and there’s almost always a plugin or theme installed that hasn’t been testing the Beta/RC versions and pushing plugin updates before that WordPress release. This is where the manifest API version system steps in, and automatically disables plugins and themes at the exact point where they are likely to break (both statistically, and technically guaranteed based on some WP changes).

      Anyway, I’d rather not debate the merits of holding back automatic upgrades to WordPress since this has already been decided among all major shared hosting companies and the WordPress Foundation already. Everyone from DreamHost, GoDaddy, Bluehost, HostGator, HostMonster, and several others have agreed that opt-out automatic WordPress upgrades are going to happen – some are already doing it. The benefits of running up-to-date, secure WordPress updates outweigh the risks of broken WordPress sites. Not to fear though, anyone with the legitimate reasons you mentioned (or linked) still have the option of staying behind. Anyway, now you can understand my concern with making sure that the automatic upgrades go as smoothly as possible with the least amount of problems, because it’s going to happen anyway.

      Switching up gears here, in regards to deprecating code, this proposal is the “managed way” of progressively deprecating code. It’s exactly right between “Never deprecate”, and “Support the latest version only.” This deprecation cycle is as solid as the development cycles designed around WordPress releases too.

      If you’re still under the impression that the core devs have “managed 100% backward compatibility” with WordPress though, I think you’ve missed the entire point of this discussion. WordPress isn’t anywhere close to 100% compatible between any single two major releases (3.3 and 3.4 for example), let alone between multiple releases. Like you said though, it’s impossible to do that with a pluggable web UI involved (i.e. allowing plugins to modify built-in pages in the admin or the frontend – but still reserving the right to make DOM changes to it in newer releases). This is mostly where and why approximately 4% of plugins break with every major release of WordPress.

      So rather than pretending to be 100% compatible, and lying about it, we need to look at some new policies like this one.

      Reply
    1. Bryan Petty Post author

      That’s awesome. I wouldn’t expect any less either. :)

      As long as the version check is the default behavior though, it’s done it’s job.

      Reply
  5. Aaron Jorbin

    My biggest problem with this idea is that it is too developer focused, not user focused. As a user, if I upgrade (by choice or automatically), and my theme changes or plugins are deactivated, then WordPress broke my site.

    Now, I think some of this could be solved by admin notices, but I wonder how much they will cause people to not upgrade, rather then seek alternatives. If I receive a notice that my theme will be deactived upon upgrading, then I’m not going to upgrade.

    Also, instead of outright removal in 4.1, I think we should just block downloading of zips and make the page only accessible to logged in users.

    I’d also move the notification to authors earlier then when they are blocked from anything besides direct visits.

    Reply
    1. Bryan Petty Post author

      That same user’s site would have broken had the plugin in question not been deactivated, or if the theme wasn’t switched. So which is better, not being able to use the admin panel or website at all, or a functional site, but missing features and appearance? We’re forced to pick one or the other during an automatic upgrade. I’m assuming it’s the latter since we can then actually notify the user in the admin panel as to what happened during the last automatic update, and inform them of how they could go about fixing it if they cared about the plugin or theme in question that was deactivated.

      I’m guessing they do care about their theme, but they also might not even be that attached to it to care about picking a new, updated theme if they know it was deactivated because it hadn’t been updated in over 2 years, and was either going to break, or potentially be a security risk.

      As for plugins though, were talking mostly about the least used plugins that provide the least amount of features and functionality since there’s literally not a single popular plugin that doesn’t ship out at least 1 update per WordPress release (3 times a year). The chance that the plugins being deactivated are ones that the WordPress user actually cares deeply about is really slim to none.

      Admin notices about a theme being changed before the upgrade is a great idea though. That is something that could easily be done.

      Reply
  6. Samuel "Otto" Wood

    Few points for now (I’m in a hurry at the moment):

    1. Creating a new “manifest” version is pointless. Use the core version for compatibility checks. We already do that in the readme.txt. No need to add more complexity.

    2. The instant we make it so that upgrading can break a site (disable a plugin or theme *is* often going to “break” a site in the user’s eyes), then we give users a very, very good reason not to upgrade again, ever. You will have a *very* hard time convincing me that any form of this methodology is now, or ever, a “good idea”.

    Reply
    1. kurtpayne

      Agreed on core version. Anything can be tied back to core version.

      As for user experience, I don’t disagree with you. But I don’t know that we have a better option.

      As I see it, we have these choices:

      1.) Keep backcompat so all upgrades work forever.
      2.) Devise a way to warn about incompatible plugins / themes, then disable them, so they don’t take out the whole site. This enables upgrading for the core and all compatible plugins / themes.
      3.) Don’t do #1 or #2 and roll the dice on every upgrade.

      Did I miss something? Is there another working system out there which does this better?

      We don’t do #1 (but close!) and we can’t agree on #2, so it looks like we’re on path #3. Users click “update now” and usually get lucky. But the user initiated the update. Before moving forward with auto update, we need to move away from a “roll the dice” strategy and make a commitment to never break anything, or to disable a particularly cantankerous plugin/theme for the good of the site.

      Reply
        1. Bryan Petty Post author

          There’s a couple problems with this too though.

          1. WordPress can’t detect when a plugin breaks due to Javascript incompatibilities, and even where we can detect if a plugin fails to activate, it’s still barely any actual code coverage, and there’s still no way to intelligently detect when just the activation breaks without generating a PHP error. We can mostly ensure that there aren’t any syntax errors in the code (since most plugins do include all PHP files), but even that isn’t guaranteed since some might be using an autoloader (PSR-0 libraries are becoming quite popular, and will be even more when WordPress drops PHP 5.2 compatibility itself). On that note, it’s possible to check syntax via command line PHP (but not available everywhere), and if you use php_check_syntax() within another PHP script, it not only checks the syntax, but also executes the script, so you can’t just run that on all PHP files included in the plugin either.

          That said, I don’t even see that as a possible solution, we will never reach a point that we can confidently claim systematically that a plugin isn’t broken during an update, it’s quite literally impossible. Besides that though…

          2. *If* automatic upgrades are turned on, there should be very few reasons why a WordPress upgrade left WordPress in a state where upgrades are halted and it leaves users on an old version of WordPress. This is acceptable if it detected that the user is running an older version of PHP/MySQL that the new version of WordPress has dropped support for (I believe the upgrader already checks this right now), but just because they have a plugin installed that isn’t compatible with the new version shouldn’t be a reason to. Given enough time, that would most likely happen to around 50% of WordPress installations (the number of installs with at least a couple non-default plugins installed based on stats from Kurt and PressTrends) with automatic upgrades turned on, and at that point, you might as well call the whole push for automatic updates a complete failure. The whole point is to turn it on, and forget about it.

          Reply
          1. Samuel "Otto" Wood

            Mobile, so, short.

            JS: definitely a problem.

            Php: plugin editor shows how to detect failure, in a simpler way than needed.

            Upgrade issues: that’s a matter of intelligently telling the user what to do next, I think.

            It’s complex, but soluble. Might take a few versions, can’t roll it all at once.

            Reply
        2. adam_silverstein

          Rollback of an upgrade would be a great feature, get rid of those pre-upgrade warnings about making a backup of the site files and database and just let the upgrade process do that. After the upgrade (auto-upgrade included), offer the user a dashboard notification, and the option to revert if something has gone wrong. also, keep snapshots of each upgrade so reverting to a previous version is also possible.

          Reply
          1. Bryan Petty Post author

            This is still something a backup plugin can (and should) take care of. There’s a few reasons this still isn’t in core. First is because WordPress simply has no way to know what to do if any single installation contains 1GB+ of uploads, or also a 1GB+ database to dump, which is very common in the case of multisite installations. There is no one-size-fits-all backup strategy for everyone. Also, since that job frequently takes longer than the average PHP execution time limit setting (and the separate CGI timeouts on top of the PHP time limit, frequently hit by IIS servers), the process of performing that backup requires additional dependencies that WordPress core doesn’t currently require on installation (namely cron with command line PHP, and some other alternative on Windows servers), so not all WordPress installs can do this. Additionally, those same installations also often have 3rd party backup solutions available to them through their hosting company that wouldn’t play well together with WordPress if they were both enabled at the same time. Since the hosting company has a much better idea of how and when backups should be done and where they can store them off-site, it’s best if WordPress leaves that up to them, and just offers quality backup plugins everyone else can use if they want to configure their own backups.

            I agree, this rollback feature would be amazing, but it’s just a fantasy if you think this will ever make it into core.

            Reply
            1. adam_silverstein

              i agree its a fantasy; i’m a dreamer. i wasn’t proposing a full backup, just the database and the wordpress core files. why would you need to back up uploads for a rollback? 1GB databases? how common are those? i guess i just don’t see them in my neck of the woods.

              maybe you are right and the functionality belongs in a plugin. i’m not sure if current backup plugins back up before upgrading automatically, but that would be a great idea!

              Reply
      1. ryannmicua

        How about adding to the list above?

        4.) Don’t automatically update WP core if a plugin/theme *seems* incompatible** – coz the plugin/theme is no longer updated. Just don’t disable the plugin/theme. Then have a bigass admin notice – that can only be taken out via js – telling the user what steps they can take. Then email the user. And keep emailing the user about it.

        ** incompatible in this case is a plugin that’s failed to keep itself updated with the version API. The plugin may still actually work.

        Of course, the user will have the option to update like what we are doing now. But at least this time, WP can *help* by telling the user which specific plugins *may* break simply because it has failed to keep up using whatever new update API that Extend rolls out. Just don’t automatically disable the theme/plugin.

        Same way how WP doesn’t upgrade if the PHP/MySQL version is old.

        And yes, it’s ok if the incompatible theme/plugin gets filtered out of Extend.

        Yes, this means that some WP installations won’t ever get updated. But at least it won’t keep back users who do use *good* plugins/themes from getting automatic WP updates.

        One counter to this would probably be – it’ll only take one incompatible plugin to keep the installation from being automatically updated. So true.

        Then, add an option to *ignore* checking this plugin – but still have a warning somewhere saying “you have opted to ignore this plugin and this may not be a good idea*.

        or maybe force the user to choose between A) Automatically Update my WP install and disable incompatible themes/plugins. B) Automatically update ONLY IF. Otherwise, let me know what I need to do.

        Yes – decisions not options. But I think this is one option that’s important enough to be there.

        My point is, we need to consider those users who choose not to upgrade or use legacy plugins for reasons their own.

        Reply
  7. CloudPress Ryan

    I like the idea. Admittedly though I find myself using a depreciated feature because it is the only way I could think of to avoid hacking core. The one bad thing about the approach is it would force me to find another creative alternative or just hack core. But it makes sense that depreciated things should eventually just be taken out all together.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s