Attracting Developers To WordPress
Ryan McCue, Senior Engineer at Human Made and WordPress Core Developer, 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 robust, future-proof platform that is easy to maintain. 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 end-users, while actually increasing the need for developers 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 Separation of Concerns, whether the code is SOLID and DRY, 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)!
1. Bump PHP Version
I know this has been talked to death already, but it is still a major obstacle. WordPress needs to bump its minimum PHP version 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.
This absolutely has to stop!
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…
Compatibility considerations:
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.
( Supported PHP Versions )
2. Use Namespaces
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 point 1. above, there’s no valid reason not to use namespaces.
Compatibility considerations:
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:
function wp_get_attachment_url( $id ) { \WP\Core\Attachment::get_url( $id ); }
3. Use an Autoloader
Once point 2. has been taken care of, it is very easy to integrate an autoloader into the mix. This goes hand in hand with point 4. below, as the package manager can tell the autoloader what namespaces need to be taken into account.
Compatibility considerations:
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.
4. Use a Package Manager
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 Composer, 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.
Compatibility considerations:
None at all, provided that point 1. above has been taken care of.
5. Use Semantic Versioning
When using an automated package manager like described in point 4., 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 Semantic Versioning 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 “we don’t break BC, ever” to “we don’t break BC for versions that are not meant to break BC“, which, as you might have guessed, paves the way for controlled breaking of BC.
Compatibility considerations:
None, this would be an easy improvement without any downside. Just start at some version and let people know what the versions mean.
6. Use Proper Object-Oriented Programming
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 “emulating namespaces with prefixes” to “emulating namespaces with classes“, which should immediately stop in favour of point 2. above.
OOP is not about syntax, it is about having decoupled objects, that communicate with each other via contracts. Everything should be coded against interfaces, 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 WP_Post
class is nice. Depending on a WP_Post
class is not. The plugins and themes should instead depend on a WP\Core\Post
interface, and know that, whatever object they will get, they will be able to call its get_title()
or render_content()
method. If WordPress Core decides to send them a WP\GitHub\MarkDownGist
which implements WP\Core\Post
instead, the theme should not need to care…
Compatibility considerations:
As with point 1. above, the current functions, classes and methods could be kept, and would redirect to Facades, that serve the purpose of an Anti-Corruption Layer 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.
OOP Examples
Point 6. 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.
Example – Routing
@rmccue It would be nice if WP_Rewrite was easier to unhook for use-cases beyond its intent. #makeitso @Rarst @gmazzap @twigpress
— Rachel Baker (@rachelbaker) March 18, 2016
@aaronjorbin @rmccue @helenhousandi No kidding. Permalinks API is WAY worst.
— Daniel Dvorkin (@MZAWeb) March 18, 2016
People don’t seem to like the way routing is handled in WordPress. Currently, the WP Rewrite API is responsible for parsing your pretty permalinks, transforming them into a WP_Query
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 WP\Core\RouterInterface
that accepts a Psr\Http\Message\ServerRequestInterface
and chooses a matching object implementing the WP\Core\RequestHandlerInterface
that can handle()
that request.
We’d then have a WP\Core\RewriteAPIRouter
that implements WP\Core\RouterInterface
to provide the current behaviour.
If you need something more than the standard WP Rewrite API, you can either replace the WP\Core\RewriteAPIRouter
with a custom implementation that implements WP\Core\RouterInterface
, or you can wrap it with a Decorator.
<3
Thank youReport
Holy damn, it’s like I wrote this myself.
But you know … even if these efforts were made, I don’t feel confident that they’d be done right. Just a hunch, maybe based on history. I’d contribute, but my skin isn’t thick enough. So I’ll leave it to people like you to prove me wrong :DReport
❤️
Wish list :)Report