Konstantin Kovshenin posted an interesting piece decrying WordPress theme frameworks1 and the extra amounts of work that they (can) require to get working Just The Right Way. Essentially, his complaint comes down to having to re-learn a system of hooks and filters in order to be cognizant of, if not competent with each of the frameworks in use. Konstantin calls out Genesis, which, to be frank, is the absolute best of the bunch2, as far as I’m concerned. Genesis, whenever and wherever possible, asks “What Would Core Do?” and then implements its innovations in a way as close to Core standards as is feasible.
I’ve actually been bothered by the same thing over time and have noticed that the net effect is that certain WordPress designers and even whole firms tend to pick at most 2-3 theme frameworks to specialize in. This leads to a bit of a “siloing” effect — designers and devs become experts in a certain way of doing things but ultimately end up being at least partly constrained by their choice of framework[s].
This also has the end effect of locking site owners into particular theme frameworks, making migrations and redesigns complicated and potentially expensive in terms of time and money.
So what can be done? I can see two approaches, the merits of which I will discuss below.
WordPress Core adds more hooks
WordPress already has quite a few hooks available, in the form of both regular action hooks and an extensive variety of template tags. These provide developers and designers with a consistent set of entry points to target for theme and site customization. If we could convince upstream WordPress to define a standard set of theme hooks, theme authors could code to a Core-supplied benchmark which would allow plugin developers greater opportunities to extend WordPress in new and better ways. Further, this would allow users in general to more easily change their theme-of-choice.
There are (at least) three decided downsides to this approach.
While the actual size of the additions would likely be small (in terms of kilobytes added to the download), there’s no denying that additional hooks would greatly increase the complexity of the underlying code.
- Explicit dependence on WordPress release cycles WordPress itself is released on a (fairly) static schedule, with roughly 2.5-3 releases occurring per year. In the event that additional theme hooks were needed, theme authors would need to wait for the next WordPress release in order to be able to rely upon the hooks being in wide use.
- This isn’t something core WordPress is/should be concerned with Frankly, the whole concept of theme hooks is self-evidently not a core WP issue. Themes currently implement their own hook regimes in order to allow for customization and flexibility precisely because WordPress itself doesn’t supply these points of articulation. This is no knock against WordPress itself, but rather this reflects one of its core strengths: the Plugin API allows for almost unlimited customization opportunities. Core WordPress should limit itself, wherever possible, to providing users and developers with the tools for customization and extension and should get out of the way so that such customization is as “frictionless” as is feasible.
Theme developers agree upon an independent set of hooks
This option makes more sense to me. As I pointed out, these hooks are something that various and sundry theme development shops have taken to implementing on their own because they want more and/or different capabilities than WordPress template tags and action hooks offer by default. Heck, I have quite a few hooks on offer in Elbee Elgee for precisely this reason (all prefixed with
lblg_, of course).
By taking this task out of the hands of the WordPress Core, we would gain quite a few advantages:
- Version independence Hook alliance member themes could debate the merits of various useful hooks and their places within themes on a timetable completely their own. There would be no need to have to wait for a lengthy Trac process and a new major dot-revision of WordPress — theme devs would be free to implement them whenever a consensus was reached.
- Know your role, jabroni!3 I’m drawing a bit of a blank on how best to summarize this thought other than “theme concerns generally exist at a level of abstraction above WordPress itself”. The code present in WordPress itself is concerned primarily with “how do we save and/or retrieve information from the database in a meaningful and orderly fashion?”4 It falls to the themes to determine
- Where each piece of retrieved information appears on-screen
- How each piece of retrieved information looks once on-screen
- Another thing to argue about, unendingly, in a place that isn’t Trac Okay, maybe that’s not a true advantage at first glance, but work with me here. How many arguments have cropped up on Trac or on the wp-hackers mailing list over issues that would be covered by the hook alliance? If a standard Core Trac reply could be “That’s a theme hook issue and not a Core one. Have you suggested something over there?”, would we not all benefit? This would allow Core developers to focus on the get/retrieve aspects where they excel and allow theme devs much greater control over their own destiny.
- Coordination with the Theme Review Team Not to put too fine a point on it, but the current incarnation of the WordPress Theme Review Team is the best example of a true community investment opportunity WordPress has going. Goals and standards are well-defined and the team itself is a large group of people working unapologetically towards making themes hew to a uniform code of quality, reliability, and security. Chip, Otto, Emil and Edward (among countless others) are to be commended for their ongoing efforts in this respect. The TRT could offer invaluable feedback in developing a uniformly useful set of agreed-upon hooks.
A simple first step would be to agree upon a standard prefix/namespace for Theme Hook Alliance hooks. I might suggest
tha_ as a good place to start. I would also suggest a few simple hooks whose purpose should be quite obvious, such as
Again, that’s just a sampler. I think there are a ton of other points of articulation that would be invaluable.
So, who’s with me in this idea? Am I crazy? Does anyone else see any utility? Who wants to argue over the utility of
UPDATE (10:03 AM): Chip points out on Twitter that this idea is not novel: it was discussed over on WP Tavern about three years ago. I think it’s time to resurrect it. *grin*
1Yes, I know the arguments about what constitutes a “framework” versus a “parent theme”. I’m working with the terms in play. Please don’t write me angry letters.
2“the bunch”, here, meaning “commercial and/or widely-used theme frameworks”.
3Do you smell what the Rock is cookin’?
4Yes, I know: gallery shortcodes and widget headers. Please don’t write.
26 Replies to “WordPress Theme Hook Alliance”
From the blog: WordPress Theme Hook Alliance http://t.co/RW0bwtzQ
@kovshenin @chip_bennett @nathanrice Could I solicit your thoughts? http://t.co/4OVtMqXd
genius idea RT @zamoose From the blog: WordPress Theme Hook Alliance http://t.co/oksCnuni
+1 RT @norcross: genius idea RT @zamoose From the blog: WordPress Theme Hook Alliance http://t.co/MugYOEro
Setting aside implementation details such as nomenclature, I am 100% in favor of a defined, standard set of template action hooks. The benefits are manifold, including:
1) Template action hooks introduce near-100% integration compatibility for any Plugin that adds content to the template.
2) Template action hooks introduce a far-superior means of Child-Theme template modification.
3) Many commercial Themes already have template action hooks, many of which are functionally interchangeable but, due to differing nomenclature, are not practically interchangeable. Introducing a standard nomenclature would introduce this practical interchangeability.
4) Introducing standard template action hooks would put more free Themes on par with many commercial Themes in terms of ease of extension/modification, in a way that would not have a steep learning curve/high barrier-to-entry.
5) Standard template action hooks would be easy to implement for those Themes (commercial or free) that already have their own template action hooks. Simply call
do_action( 'standard_template_hook' )as a callback to
add_action( 'theme_custom_action_hook' )for each template action hook.
6) Template action hooks would in many ways ease core bloat/complexity. See, for example, this ticket discussing the difficultly in implementing a universal means to apply content after the post.
I am far more interested in the idea/principle of standardizing template action hooks than I am in determining the nomenclature. Universal adoption of the former is far more important than universal agreement on the latter. (Whether I implement tha_before_header or header_before or oenology_hook_header_before, what is important is that an action hook is provided in the template, before the site header is output.)
So, if there are people heavily invested in the template action hook nomenclature, let them decide that nomenclature, then let’s standardize on adoption of the hooks.
Hi Doug! Thanks for the mention! I can’t believe my lousy post created so much noise 🙂 Theme Hooks Alliance, ha! I really like the sound of that! I can’t really think of a good way I’d use any of the hooks you mentioned, I mean themes are really markup specific, right?
If you wanted to add a something before your parent’s theme (framework, or whatever) header section, in your scenario you’d have to create a child theme, a functions file, hook into the
tha_before_headeraction and output your markup. I really dislike markup in functions.php, especially for something that really smells like header.php markup. Why isn’t it in header.php in the first place?
This made me think of a “Get Template Part Alliance” ha! The exact same idea, but replace
get_template_part, to look for files named before-header.php, after-header.php and so on, and if the child theme has such files, it’ll find it, if it doesn’t, it won’t include anything. Boom! How’s that? 🙂
Just make sure you do
get_template_part( 'before-header' );and not
get_template_part( 'before', 'header' );, which essentially may lead to the same thing, but if for some reason it finds a file called before.php (and not before-header.php), it’ll start falling back to it.
That’s just off the top of my head. Anyway, I’m really interested to see where you can take this whole alliance idea, so best of luck!
Not in the least. All Themes have a site extent, site header, site footer, content (loop) area, post container, comments container, etc. All of these common features – comment template locations – can be taken advantage of using a standard, universal set of template action hooks.
The idea isn’t for the hooks to be implemented via Child Theme, but rather for the hooks to be adopted by all Themes, so that the same, standard set of hooks is available to every end user, every Child Theme, every Plugin developer, etc.
I would suggest, though, that limiting oneself to the templates regime is a step too far. Unless I’m very much mistaken, one cannot attach multiple sub-templates to a single area, whereas action hooks allow a virtually unlimited number of functions to be added to them.
Let’s take a simple case. Say I have a nav menu that, by default, resides at my
tha_after_headerhook. That is, I have my site title, header image, ad banner, whatever, displayed first and then I have my nav menu. Using a simple
remove_/add_action()call in my child theme, I can seamlessly move my nav menu to the
tha_before_headerhook, thus moving nav to the top of my site.
Further, I want a secondary menu displayed below the primary one. The parent theme doesn’t supply one, so I add another menu via my
functions.php. In the template scenario, I’ve got to supply an entirely new template part to override the parent theme’s component, meaning I have to cut and paste the markup from the parent into my child template part and then add my markup. That’s duplicative and wasteful. Instead, I simply hook into
tha_before_headerwith a lower priority than the primary menu and BOOM! secondary nav. Very efficient, no duplicated markup.
A call to wp_nav_menu isn’t markup, that’s just a function call 🙂 register_nav_menu is also a function call, and functions.php is for function calls, so your case is 100% awesome. When I said a bunch of markup in your functions file, I meant like copy the contents of header.php and paste it 10 times in a row.
I don’t see why you can’t hook a call to get_template_part to that before_header action, yeah it’s an extra step but I don’t mind. Someone who doesn’t know actions might. It’s easier to explain get_template_part than it is to explain actions and filters 😉
Anyway, I agree with you and Chip, and you have my full support. I’ll implement whatever you guys say in a couple of themes I maintain, and will use the special badge too! Uhm.. Do we have a special badge for alliance members? 😀
Chip also shared this: http://www.wptavern.com/forum/themes-templates/494-standard-theme-hook-names.html
This would be for theme authors, yes, but also for plugin devs, some of whom are enthusiastic at the prospect and can freely mix code and markup to their hearts’ content. *grin*
RT @zamoose: From the blog: WordPress Theme Hook Alliance http://t.co/RW0bwtzQ
I don’t think there’s any need for a prefix. What I would rather see is this have it’s own space (maybe on the Codex?) and get input from some core developers, so they know not to use the hooks we come up with in core anywhere.
For instance, this hook:
do_action( ‘before_content’ );
The core developers would need to know not to use that action anywhere in core, so we can avoid conflicts.
There also needs to be plenty of discussion as to the exact placement of these hooks, with lots of documentation and example code for theme developers, if we want mass adoption.
Also, it would be good if the Theme Repository review team could use these hooks as part of their standards list, require new themes to use these hooks when submitting to the repo, and encourage old themes in the repo to adopt the standard, including twentyten and twentyeleven (and, presumably, twentytwelve).
I’m happy to push this into Genesis 1.9.0, as well.
I disagree, based upon the fact that what I’m advocating for is a third-party solution and one that wouldn’t rely upon Core for ratification/reification. If that’s the tack to take, then we are better off using the first approach — advocating for specific location hooks to be folded in to Core.
Namespacing could have further advantages as well. Consider the following use case:
Perform a simple grep on a theme tree for instances of “tha_” (or whatever prefix is agreed upon). You will quickly be able to evaluate just how many of the Alliance hooks a theme implements. If we were to use simpler or more generic hook names, this advantage would immediately be lost.
The standard hooks thing may eventually become a reality, and getting core devs involved might push them along a bit faster. It’s worth a shot. If they refuse, we do it sans core dev support via the Alliance.
I like the add_theme_support shim for the short run. That obviously would have to have core buy-in.
I’m working on an alternative solution currently.
I’m torn. On one hand, using a custom prefix facilitates immediate adoption, and poses no possibility of core conflict. On the other hand, using a custom prefix creates a barrier to adoption if template action hooks are ever implemented (sanctioned? recognized?) by core.
So perhaps a two-pronged approach is in order? Given that the nomenclature (including prefix/no-prefix) is secondary to standardizing on the template locations to which to add action hooks, and to adoption of such hooks, I see no reason that we can’t approach the issue from both directions: a third-party/external solution, and core.
Do you want to carry on the discussion of formulating the list of template action locations here, or perhaps at the make.themes site? I would be happy to start it there, or to direct Theme developers here.
I’ve started a Github project. It will have a basic README and a PHP file containing function/do_action definitions.
Let me know if that sounds like a good direction to take. It seems more efficient than a P2-based solution.
Dan Cole’s original attempt at a hook standard:
Whoops. I picked up a Trac ticket as what you were referencing instead of that Codex article.
Nathan actually linked to that ticket up-thread. Guess I’m more echoing a long-standing desire than a though innovator. *grin*
The biggest problem with standardizing anything on the front-end of WordPress is creating a reliable set of expectations. I don’t believe a simple set of hooks is going to do anything to provide that reliability.
Standardized hooks for above and below content would be a boon not just for people creating customized themes but for plugin authors as well. However, just adding the hooks for this without any other kind of markup standardization does very little to help things.
The problem comes into play when considering where calls to such hooks should be placed and how things should be styled. Without any standardization in place for this, we return to a wild west of “my way is best” and simply trade one problem (how do I get my feature in that spot on every theme) with a new one (how do I make my feature not look like crap on 80% of the themes).
My point is that any discussion about standardized hooks for theme templates should also include discussion about implementation details and expectations. Leaving these important considerations out would create solutions of very little value. Sure, maybe they would be nice for theme customizers, but if the utility and reliability can be extended to plugin authors as well, why not aim for that goal?
Thanks for the feedback! I think you and I are thinking in the same directions. Please check out the Github project and see if I’m headed in a direction compatible with your critiques. In particular, I have an example index file that highlights where the hooks should go.
Again, I appreciate any and all feedback.
Looks good to me! Though let’s not ditch
wp_footer, okay? 🙂
Crap, I knew I’d forgotten something. Good catch.
Git commit incoming.
Or you can just accept that pull request, so I can tell everyone I contributed to your project 😀
Done! In like Flynn.