---
title: Attracting Developers To WordPress
canonical: "https://www.alainschlesser.com/thinking/attracting-developers-wordpress/"
pubDate: "2016-03-19T00:00:00.000Z"
updatedDate: "2016-07-10T00:00:00.000Z"
author: Alain Schlesser
description: "WordPress courts end-users while quietly demanding more of developers, and that paradox drives much of the friction. A six-point opinionated roadmap — PHP floor, namespaces, Composer, SemVer, real OOP — each paired with a backward-compatibility path through facades and anti-corruption layers."
tags: [WordPress, Software Architecture, "OOP & Design Patterns"]
---

<a href="https://twitter.com/rmccue" target="_blank">Ryan McCue</a>, Senior Engineer at <a href="https://hmn.md/" target="_blank">Human Made</a> and <a href="https://profiles.wordpress.org/rmccue" target="_blank">WordPress Core Developer</a>, has posted a series of tweets regarding the fact that WordPress is far from an ideal platform for developers, which has spawned a lot of discussion.

https://twitter.com/rmccue/status/710464212183572481

https://twitter.com/rmccue/status/710469646680399874

As a long-form response to this, here's a list of changes I would like to see in WordPress, and how I would try to address backward compatibility (BC) concerns. I don't pretend to know that this is the absolute best way to tackle the problem, this is purely my own biased opinion, and how I would try to fix the issues if I were in charge.

Keep in mind that I am mostly interested in having a <strong>robust</strong>, <strong>future-proof</strong> platform that is <strong>easy to maintain</strong>. Some of the changes proposed below might be a disadvantage to the end-users without a developing background. One of the major hurdles that WordPress currently faces is that it tries to focus on <strong>end-users</strong>, while actually increasing the need for <strong>developers</strong> to implement solutions. That one paradox is probably at the heart of a lot of drama in recent times.

I also want to mention that I don't list any of the more implementation-specific details, like whether there is a <strong><a href="https://en.wikipedia.org/wiki/Separation_of_concerns" target="_blank">Separation of Concerns</a></strong>, whether the code is <strong><a href="https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)" target="_blank">SOLID</a></strong> and <strong><a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a></strong>, etc... I only concentrate on the critical path from the now to a future where we can more easily get rid of cruft and improve at an accelerated pace. Once this we've enabled this, taking care of the implementation specifics should be a piece of cake (hopefully)!

<h2 id="bump-php-version">1. Bump PHP Version</h2>

I know this has been talked to death already, but it is still a major obstacle. WordPress needs to bump its <strong>minimum PHP version</strong> requirement (not the recommended version). With great power comes great responsibility, and all the bragging about running one quarter of the web has a very bitter taste to it because of this.

It is completely irresponsible and totally inexcusable to run a web server on PHP version 5.2 in 2016. By keeping the requirements this low, WordPress only caters to the people not ever looking after their servers, and the web hosting companies that sell very shoddy services to unknowing customers.

<strong>This absolutely has to stop!</strong>

Any serious hosting solution will keep their PHP version as current as possible, even if only to save money on reduced resource usage. I might even go so far as to connect the word "malicious" to 5.2 hosting...

<span style="text-decoration: underline;"><strong>Compatibility considerations:</strong></span>
None, that's the whole point. Drop the compatibility with any version that has no security support, preferably even versions that have no active support.
<em>( <a href="http://php.net/supported-versions.php" target="_blank">Supported PHP Versions</a> )</em>

<h2 id="use-namespaces">2. Use Namespaces</h2>

Developers have known for many decades now that polluting the global namespace is bad, and that it will come back to bite you. The fact that PHP was late to the party with introducing namespaces does not mean that we can continue to ignore this now.

Imagine having all of your files (your photos, your videos, your documents, your operating system's files, your applications' files, ...) be regrouped in one single folder. Bad idea, right? Everyone knows that....

So, once we've dealt with <a href="#bump-php-version">point 1.</a> above, there's no valid reason not to use namespaces.

<span style="text-decoration: underline;"><strong>Compatibility considerations:</strong></span>
To make the initial switch and provide legacy support for some time, the current functions can still stay and just redirect to the corresponding namespaced variants:

```php
function wp_get_attachment_url( $id ) {
    \WP\Core\Attachment::get_url( $id );
}
```

<h2 id="use-autoloader">3. Use an Autoloader</h2>

Once <a href="#use-namespaces">point 2.</a> has been taken care of, it is very easy to integrate an autoloader into the mix. This goes hand in hand with <a href="#use-composer">point 4.</a> below, as the package manager can tell the autoloader what namespaces need to be taken into account.

<span style="text-decoration: underline;"><strong>Compatibility considerations:</strong></span>
None at all, autoloaders are already used all the time within WordPress plugins and themes. Combined with a proper architecture, an autoloader in WordPress Core will probably improve performance and memory consumption.

<h2 id="use-composer">4. Use a Package Manager</h2>

Every non-trivial project reuses existing libraries and components. To avoid manual updating chores, this should be controlled and automated through a package manager, that pulls in dependencies and sub-dependencies. If this is combined with a corresponding way to define the needs of the project, the number of dependencies pulled in for WordPress Core could even be drastically reduced for most projects.

In the PHP world, the de-facto standard for package management is <strong><a href="https://getcomposer.org/" target="_blank">Composer</a></strong>, and I don't see any valid reason not to use this as the package manager for WordPress projects. In fact, many developers already use Composer at the site level to update their entire project with one single command, with WordPress Core just being one of the many dependencies of a WordPress project.

<span style="text-decoration: underline;"><strong>Compatibility considerations:</strong></span>
None at all, provided that <a href="#bump-php-version">point 1.</a> above has been taken care of.

<h2 id="use-semver">5. Use Semantic Versioning</h2>

When using an automated package manager like described in <a href="#use-composer">point 4.</a>, it becomes hugely important to be able to control updates in an automated way, and to stop updates if they would break BC.

That's what <strong><a href="http://semver.org/" target="_blank">Semantic Versioning</a></strong> is for. It would provide a way for automatic updates to just stop right before a BC would be introduced, and to also have security fixes that can be applied to previous, legacy versions.

This would change the WordPress BC philosophy from "<em>we don't break BC, ever</em>" to "<em>we don't break BC for versions that are not meant to break BC</em>", which, as you might have guessed, paves the way for <strong>controlled breaking of BC</strong>.

<span style="text-decoration: underline;"><strong>Compatibility considerations:</strong></span>
None, this would be an easy improvement without any downside. Just start at some version and let people know what the versions mean.

<h2 id="use-oop">6. Use Proper Object-Oriented Programming</h2>

I know that OOP is not the holy grail of development, but for a system of any non-trivial complexity, it is still heaps better than a procedural approach when it comes to maintainability and extensibility.

The procedural code is in fact one of the reasons why it is so difficult to make changes to WordPress Core without breaking BC. You can't just extend an object and simply pass the extended version down the pipeline... there is nothing to extend, and there is no pipeline (whatever that may be), the plugins and themes are directly coupled to some of the innermost implementation details.

I've seen lots of efforts in this direction already, but I have to say that most of the "classy" code in WordPress Core is still very much procedural code written in class syntax, and the whole purpose is to switch from "<em>emulating namespaces with prefixes</em>" to "<em>emulating namespaces with classes</em>", which should immediately stop in favour of point 2. above.

OOP is not about syntax, it is about having <strong>decoupled</strong> objects, that communicate with each other via <strong>contracts</strong>. Everything should be coded against <strong>interfaces</strong>, not concrete implementations. This way, the objects can be easily extended, and their implementations can be changed without breaking anything any dependent code.

So, having a <code>WP_Post</code> class is nice. Depending on a <code>WP_Post</code> class is not. The plugins and themes should instead depend on a <code>WP\Core\Post</code> interface, and know that, whatever object they will get, they will be able to call its <code>get_title()</code> or <code>render_content()</code> method. If WordPress Core decides to send them a <code>WP\GitHub\MarkDownGist</code> which <code>implements WP\Core\Post</code> instead, the theme should not need to care...

<span style="text-decoration: underline;"><strong>Compatibility considerations:</strong></span>
As with <a href="#bump-php-version">point 1.</a> above, the current functions, classes and methods could be kept, and would redirect to <strong><a href="https://en.wikipedia.org/wiki/Facade_pattern" target="_blank">Facades</a></strong>, that serve the purpose of an <strong><a href="http://ddd.fed.wiki.org/view/anticorruption-layer" target="_blank">Anti-Corruption Layer</a></strong> between the current code and the new OOP code. The OOP code should be built to provide an optimal model, and ignore the requirements of the legacy code. The Facade will then translate between these two.
Using this approach, the new model can be built alongside the legacy one, and they can coexist as long as is necessary to get everyone migrated to the new model.

<h2>OOP Examples</h2>

<a href="#use-oop">Point 6.</a> is the biggie and should be the goal for the foreseeable future. Once there are proper abstractions for all the major subsystems and models that WordPress Core uses, and provided that they are properly decoupled from each other, it becomes trivial to replace specific parts with custom implementations.

Let's take one of the suggestions people provided as an example and try to imagine how that could work in a proper OOP WordPress, so that it can be easily extended/customised.

<h3>Example - Routing</h3>

https://twitter.com/rachelbaker/status/710798022737858560

https://twitter.com/MZAWeb/status/710644905123651584

People don't seem to like the way routing is handled in WordPress. Currently, the <em>WP Rewrite API</em> is responsible for parsing your pretty permalinks, transforming them into a <code>WP_Query</code> request, and dispensing developer headaches along the way. What would a flexible, extensible routing system look like for WP?

Well, at a very basic level, we need a <code>WP\Core\RouterInterface</code> that accepts a <a href="https://github.com/php-fig/http-message/blob/master/src/ServerRequestInterface.php" target="_blank"><code>Psr\Http\Message\ServerRequestInterface</code></a> and chooses a matching object implementing the <code>WP\Core\RequestHandlerInterface</code> that can <code>handle()</code> that request.

We'd then have a <code>WP\Core\RewriteAPIRouter</code> that <code>implements WP\Core\RouterInterface</code> to provide the current behaviour.

If you need something more than the standard <em>WP Rewrite API</em>, you can either replace the <code>WP\Core\RewriteAPIRouter</code> with a custom implementation that <code>implements WP\Core\RouterInterface</code>, or you can wrap it with a <a href="https://en.wikipedia.org/wiki/Decorator_pattern" target="_blank">Decorator</a>.

<h3></h3>
