WordPress is rapidly facing an issue that its competitor CMSs have long since solved… Namely that relationship between Core, Plugin and Theme.
M V C
Without a doubt in my mind, WordPress’s theming engine is the most simple to grasp, and as Kimb is quick to point out, it’s how WordPress won the war.
In terms of blogging, and it’s 1-to-1 nature, there is a fairly clear separation between the 3 sections. Plugins allow additional information / processing to the Core, which in turn displays themes. That works 99.9%.
In order to facilitate this the WP Core Team have continued to pile features and decision making into the THEME, a place that really shouldn’t have any decision making powers. The THEME really should be the simple view for displaying or outputting of data.
The obvious example of this is add_theme_support() and thumb nails. Plugins can register custom post types, which is the correct way to do this, and can set up a list of the admin / back-end features it supports:
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail' ),
The issue is that unless the Theme also supports all of these features for each plugin, by calling them out individually, then these features won’t work even in the back end.
Clarification of the Theme vs. Plugin issue
A plugin telling the admin backend (nothing to do with a front-end theme) that it supports featured images, won’t be allowed to support featured images in the admin back-end (nothing to do with the front-end theme) unless the front-end theme specifically also “adds_theme_support” for both that feature AND the plugin.
It’s madness. We have reached a stage where the front-end theme is dictating not only what features can be loaded on the front-end, but also what can be loaded into the back-end admin area. The current setup works on the presumption that your theme knows of every plugin and Custom Post Type that your WordPress installation has, and that it somehow magically know what data you want to add to your backend system, and why.
Between you and me, when i hear two separate systems of functionality overlapping and the phrase “magically” involved, I get a little worried.
The problem with themes are growing.
Rather than boring you with the rabbit hole that we’re going down, let me tell you how we can stop it….
Change 1: Themes shouldn’t impact the backend
What we need is for plugins that add features to “supported” to not be natively overwritten by themes.
They are completely independent, and should stay so.
I mean, a theme shouldn’t stop excerpts from being entered into the admin area, even if they’re not shown at the front end. The same rules should be in place for every support feature, otherwise, that’s the point of the support attribute.
The back-end and front-end are separate, and should stay separate.
Change 2: Theme dependancies
By moving PLUGINs to the most important part of the MVC controller, we can specify what plugins a theme is dependant upon before loading.
It really could be an exceptionally simple text file included in each theme, listing plugins:
$theme_dependancies = array(
"must_have" = array('akismet', 'genesis_framework', 'all in one seo')
"should_have" = array ('bbpress')
"could_have" = array ()
Why would this be beneficial?
- It would remove the need for theme frameworks to be embedded in in themes. (less files, less dependant programming).
- It would prepare for better defensive programming (e.g. if function_exists )
- It would push people to use Classes more than simple functions
- It would allow people to extend framework classes for particular usage.
- It would allow bugs, code and functionality to be updated independent of themes; so that themes could be once again about the output of data.
- It would allow theme developers the chance to add additional functionality that works well with popular plugins.
(e.g. If X plugin/function exists do Y, if not do Z)
More importantly, this is as backward compatible as it is a scalable solution. Effectively it’s “opt-in”. A theme without any plugin dependancies works exactly as it would do right now.
Change 3: Theme, plugin & get_template_part()
Get_template_part needs an overhaul. A major overhaul.
Right now it’s simply a wrapper function for locate_template, but actually causes more problems than:
We need to be able to register templates. That way the locate_template function can check an array without having to look for files.
- This would allow plugins to register templates.
- Themes, frameworks and plugins could embed template files in multiple folders.
- Child themes could be loaded via plugins
- Child themes wouldn’t need to stick to the exact same folder structure.
We need to be able to pass a variable through get_template_part.
Calling global variables fails to work when iterating through multiple iterations of get_template_part; which happens often in n-to-n recursion
(e.g. get_template_part (row), and in each row it gets_template_p (columns); )
If we ever move to a WP_THEME class, adding these 3 simple code features would make a HUGE amount of difference to both theme and plugin developers.
It would greatly simplify so much of the workflows and workarounds that we currently have to do to make WordPress work effectively.
Why is this even an issue?
Other than instituting good development practices, it also allows both Automattic/WP.org and Plug-in/Theme owners react quicker to issues and really maintain their code once the user has downloaded it.
Imagine being able to push out bug fixes to themes/frameworks and open source libraries within hours, without fear of actually messing up a theme on the front-end.
We all know that WordPress is a prime-beef target for spammers and hackers. It won’t be long until a popular plugin or theme is targeted, or worse, an open source library thats include either in the core (e.g. SimplePie / ezSQL) or in themes (e.g. TimThumb).
When that happens, regardless of how quickly the core or the wordpress community reacts, the long tail effect of people being simple UNABLE to upgrade or UNAWARE due to the disconnect will mean that any issue has the devastating potential to continue to haunt people for months (if not years).
We have a chance to do this better.
We have a chance to do this in a managed way.
Best of all, what I’m proposing is purely opt-in. I understand the desire for “decisions not options”, and one-click themes; but as we move to a more distributed user-base and to more and more CMS-type uses of WordPress, we can not continue to hope that “what got us here, will get us there”.