Why I’m Against Placing Custom Hooks in WordPress Themes

One of the things that I my team and I are often asked is if we’re ever going to place hooks in our core theme files for Standard. The short answer is “no,” but there’s actually a few reasons why I’m personally against placing custom hooks in WordPress themes.

Although this is stemming largely from building and managing a commercial theme, the discussion isn’t limited to that particular scenario. Rather, this is something that I’ve actually discussed with a number of other WordPress users and developers.

Overall, I’m generally against placing custom hooks in WordPress theme files, so I thought I’d share my reasons why I’m not a fan of doing this.

1. The Purpose Of Hooks

As defined by WordPress in the Codex:

Hooks are provided by WordPress to allow your plugin to ‘hook into’ the rest of WordPress; that is, to call functions in your plugin at specific times, and thereby set your plugin in motion.

Simply put, hooks exist that allow our themes and our plugins to modify core WordPress behavior. This is usually done by actions and/or filters.

Actions allow us to do something during the WordPress page lifecycle, and filters allow us to modify data before it’s written to the database, written to the screen, or written somewhere else.

It’s powerful, sure, but hooks existing in the WordPress application core for themes to modify. Custom hooks shouldn’t exist at the theme level for other developers to modify.

2. This Negates Child Themes

The reason that custom hooks should not exist at the theme level is because it negates the need for child themes.

Again, from the Codex:

A WordPress child theme is a theme that inherits the functionality of another theme, called the parent theme, and allows you to modify, or add to, the functionality of that parent theme.

If a parent – or base – theme is developed using WordPress best practices, then extending it is a matter of creating a child theme and customizing the templates and having the developer manage hooks in his or her own customization.

The responsibility of a theme developer is to make sure his or her work is child theme-ready. From there, future developers can extend the theme by customizing templates and leveraging existing WordPress hooks – not custom theme hooks.

3. It Perpetuates a Poor Practice

Introducing custom hooks and filters into your theme is perpetuating a poor practice. This goes against “the WordPress way” of building themes by allowing users to customize their theme in non-standard WordPress ways.

Unfortunately, there are a number of themes – and very popular ones, at that – that have been doing this for sometime now. And when a successful theme does this, others build the same functionality into their theme. After all, if Successful Theme has done this, why shouldn’t we?

But this damages the WordPress community by perpetuating a poor practice. Aside from “doing it wrong,” it gives less experienced developers the idea that this is an acceptable practice and sets a level of expectation for customers that should not have to be met.

It becomes a bit of a vicious cycle: themes that start off by doing this and gaining success are locked into continuing to do this because their customer base is leveraging the existing hook system. On top of that, those customers expect other themes who are “doing it right,” to introduce this functionality into their core product.

This creates a completely unnecessary segmentation in the WordPress market based solely on a poor practice.

The Plugin Exception

A quick word about plugins: plugins are different in themes in that plugin developers may want to support add-ons for their work. Specifically, they are looking to make their plugin extensible.

Because there is no notion of “child plugins” nor facilities for easily extending plugins, then plugins should have a hook system in place that allows developers to do exactly that.

But plugins are different than themes and aren’t meant to play by the same rules.

Anyway, it’s clear that I dislike this practice and I’d love for it to stop, but the fact of the matter is that as long as there are developers who care more about shipping a product that works with a disregard for the best practices than building the best product possible using the best possible standards, and as long as there are people who are willing to pay their hard-earned money for it, I don’t see it stopping.

With that said, the work that both my team and I do personally will not follow these practices. They’re against the fundamental WordPress way of doing things and I’d rather contribute something positive and educate our customers than arm them with something that’s setting them up for doing it the wrong way.

21 Replies to “Why I’m Against Placing Custom Hooks in WordPress Themes”

  1. These are some great points you brought up. But let me get this straight, are you trying to say themes should not extend WordPress core simply because it says so in the codex? I think that themes are meant solely to control the appearance of the site (which has nothing to do with extending core) and other functionality should be the responsibility of plugins.

    Out of curiosity, what’s your take on frameworks such as Genesis, Hybrid Core, and so on? From what I understand, seems like you relate to them too, as they are meant to be extended by child themes.

    Oh, and you got a little typo up there

    It’s powerful, sure, but hooks existing in the WordPress application core for themes to modify. They shouldn’t exist at the theme level for other developers to modify.

    1. Are you trying to say themes should not extend WordPress core simply because it says so in the codex?

      Absolutely not! I’ve added a couple of points of clarification in the post so thanks for bringing this up.

      Themes need to leverage those hooks that WordPress provides to give themselves whatever functionality they’re aiming for. What I’m saying is that themes should not introduce their own custom hooks into their core. That’s precisely what child themes are for – extend the base theme, then leverage WordPress’ existing hooks.

      I’ve mad respect for the guys at StudioPress and the Hybrid Core Team – I want to be clear about that. Personally, I’m not a fan of frameworks, but that’s for personal reasons not to say they don’t have their place in the WordPress ecosystem. Perhaps I’ll devote a post about this in the future :).

      And thanks for the heads up on the typo – resolved!

  2. When I first read your post, I thought you were arguing against the very concept of providing template hooks in Themes, and was prepared to argue vigorously against such an assertion. However, based on Twitter conversation, it appears that the issue isn’t the concept of template hooks per se, but rather the proliferation of non-standardized or custom Theme template hooks.

    Many commercial Themes – and the biggest and most well-known, at that – implement a custom template extension API, by defining their own, custom Theme template hooks. Thus, end users and developers are locked in to those Themes, once they start writing code to use their custom hooks APIs.

    So the issue isn’t the template hooks API itself, but rather that Themes are implementing custom, rather than standardized, template hooks APIs.

    The solution to that problem, then, is a standardized Theme template hooks API, that can be adopted universally by Theme developers. Fortunately, and finally, such an effort is underway: the Theme Hooks Alliance.

    The beauty of this approach is that it is easy to implement for Themes that have never added template hooks, and it is even easier to provide a compatibility layer for those Themes that have already implemented their own custom template hooks.

    Would you be willing to help support and proliferate such an effort?

    1. I agree with Chip, and I have lots of respect for who came up first with this idea.
      I think that, the same way we have W3C for legislating internet standards, we should be having an entity, or even a simple bundle of hooks like THA, that will set up some standardized custom hooks that will be used across many Themes. I think that the apple doesn’t fall far from the tree simply because we have witnessed many Theme authors integrating Timthumb into their Themes. So it’s safe to assume they might be willing adopt THA.

    2. You’re absolutely right – I’m all for hooks in themes. I can’t imagine not using – it’s what they are there for, it’s what allows these to provide unique functionality, and it’s how we tap into WordPress core.

      What I dislike is custom hooks that themes provide rather than support child themes and then letting them default to overriding the base theme’s templates and then writing their own custom functionality into the core WordPress hooks.

      So the issue isn’t the template hooks API itself, but rather that Themes are implementing custom, rather than standardized, template hooks APIs.

      And this is exactly what I’m arguing against. I’m not a fan of it. I don’t think it’s the right way of doing things.

      Now, I’m intrigued by the Theme Hooks Alliance, but I’ve yet to read enough on it to form an opinion … yet.

      When I do, I’ll likely discuss it here :).

  3. I like the idea behind what you are saying, but it seems to be more of a “pie in the sky” idea than something that has a realistic solution. The problem with standardizing hooks and filters for Themes is just that – you have to standardize hooks and filters for thousands upon thousands upon thousands of innumerable combinations of theme layouts, styles, designs and implementations. There is no possible way that you can reliably code in that scenario and expect the same type of output across the board. In fact, that would be incredibly frustrating as a developer to never know if the “standardized” hook you are using will actually function as it is supposed to. To put it bluntly, the average theme author isn’t smart or savvy enough to know how to do it right – and for something like this to work, it has to be done right.

    You could take a step back from themes and apply this same argument to WordPress itself. What is WordPress? A content management system, a PHP application, a PHP framework, a PHP “theme” if you will. I’m sure you could make the same argument about PHP frameworks, but the success of WordPress, Zend, Symfony, CakePHP (amongst others) and the standardization of approaches within their own ecosystem is sufficient for the majority of the developers that use them. Or think Rails for Ruby or Django for Python..

    Again, I like the idea – I just don’t think it is a realistic one seeing the proliferation of web application frameworks that each have their own set of standards.

    And along the issue of child themes, I’m all for using them as well, but what happens when you want to change something simple like the order of post meta for a post? Not that performance is going to be affected, but that means you have to copy over the whole flow of code just to change the order of something simple. Again, it may not be standardized, but it is definitely more efficient have some sort of custom filter to alter that data.

    Anyway, it’s clear that I dislike this practice and I’d love for it to stop, but the fact of the matter is that as long as there are developers who care more about shipping a product that works with a disregard for the best practices than building the best product possible using the best possible standards, and as long as there are people who are willing to pay their hard-earned money for it, I don’t see it stopping.

    Where are these best practices? Who has defined them? If we are still trying to create standards for this issue, best practices by merit or the argument can’t exist yet. :-)

    I usually dig everything you write here (keep up the good work!), but I’ve got to respectfully disagree with this point. :-)

    1. I don’t agree that it’s a “pie in the sky” solution because it’s exactly how WordPress works today:

      • You write a base theme that leverages core hooks.
      • Make sure to use functions that are child theme compatible (such as get_template_directory_uri rather than get_stylesheet_directory_uri, for example.
      • Then let the child them inherit the parent’s base changing whatever it wishes to customize either via WordPress hooks, modified templates, or both.

      Because of the “standardized” hooks that WordPress provides, that’s exactly why we can code reliably. My point in the post is that placing custom hooks in themes provides the opposite effect – you have to know the theme rather than WordPress-itself in order to code reliably against it. That isn’t how it should be.

      To your point about the average theme author, I think you raise a great question – why aren’t they savvy enough to do it, right? Generally speaking, I think it’s divided. There are some great theme authors who get it, then there are those that don’t. That’s the nature of the market, but if they opt not to do it is it their fault for not pursuing information enough and simply going with “whatever works,” is it the community’s fault for not doing enough evangelization, are we all to blame? Probably the latter, but I don’t know :).

      But the point you’re making about frameworks like CakePHP and Ruby on Rails are exactly why I think custom hooks are a bad idea. Both of those frameworks offer, for example, “The Rails Way” of doing something – there’s convention over configuration. Similarly, WordPress has that with their standardized set of hooks. Deviating from that is what I’m arguing against – custom hooks are the deviation.

      So, with child themes, there may be a level of copying over a template in order to change post meta, but because of the way that WordPress is built and assuming that the developer has properly created the base theme, then there won’t be any issue in doing that. Creating a custom filter to change the way post meta is rendered when the correct way would be to create a child theme and customize that specific template is how WordPress does its thing, you know?

      And I do think a foundation for the argument exists (otherwise, I wouldn’t be writing about it ;)) – I define best practices as a combination of the WordPress API, the Theme Development Guidelines, and Child Theme Guidelines, all of which are expected to should be followed when developing WordPress-based projects.

      To that end, these are the standards and best practices on which I base my arguments – documented, enforced (in so far as they can be enforced) using certain plugins, and evagelized by the Theme Team at Automattic.

      Finally, fantastic comment – disagreements don’t bother me :). I dig the discussion that comes from this kind of stuff, and love hearing what the rest of you guys have to say.

      It’s half the reason we blog, right?

      1. Because of the “standardized” hooks that WordPress provides, that’s exactly why we can code reliably. My point in the post is that placing custom hooks in themes provides the opposite effect – you have to know the theme rather than WordPress-itself in order to code reliably against it. That isn’t how it should be.

        You can make this argument too with WordPress. If you start out developing with WordPress, you don’t know PHP. You know WordPress. You’ve got to know WordPress to code reliably against it, even if using some standard PHP mechanisms would make more sense. But those who use WordPress won’t argue that that isn’t how it should be done. They would most likely argue the opposite (and I’d be one of those people). Why? Because it’s standardized to WordPress.

        I don’t think it’s crazy to present themes in the same light. I love Genesis, and part of the reason why is that is has a standardized set of hooks and filters that I can use reliably when developing a child theme. Genesis most definitely follow WordPress coding standards and has completely support for child themes, but it also provides a standardized way to people to interact with the theme. Maybe standardizing themes is something WordPress should do, but primarily as a blogging/CMS platform, I think that may be asking and reaching for too much.

        What we can do is promote the correct way to create child themes and promote the correct use of hooks and filters, standardized or not. I think there is a lot of movement around that type of thinking in WordPress, and I am behind that 100%.

        Both of those frameworks offer, for example, “The Rails Way” of doing something – there’s convention over configuration. Similarly, WordPress has that with their standardized set of hooks. Deviating from that is what I’m arguing against – custom hooks are the deviation.

        When you separate presentation from application (a la theme from WordPress), I don’t believe custom hooks are the deviation. Custom hooks are utilizing the core API of the application, standardized or not. Creating custom database queries to get information that WordPress has already created a function or method for – that’s a deviation that should be addressed.

        Creating a custom filter to change the way post meta is rendered when the correct way would be to create a child theme and customize that specific template is how WordPress does its thing, you know?

        TwentyTwelve does both – and it ships with core. ;-)

        To that end, these are the standards and best practices on which I base my arguments – documented, enforced (in so far as they can be enforced) using certain plugins, and evagelized by the Theme Team at Automattic.

        To the standards that you listed and linked to, none of them offer advice or a specific way to approach custom hooks. Genesis or Hybrid follows the same set of standards, too, and I’d be willing to bet that they would pass the plugin and review tests just the same as Standard.

        To be sure, I think you have an excellent argument too. Since a lot of my time is spent developing plugins, I’d love to see standardized hooks that I could use and know that something is going to work on every theme that utilizes the standardized set. I get that and can completely see the argument behind it. Not having to filter the_content() to get something to appear in a theme’s main portion of content would be a glorious thing.

        But until that day comes, custom hooks and filters are to themes/plugins as -webkit and -moz are to CSS, and there aren’t many developers who are going to ignore the functionality and flexibility they provide because it’s not “standardized” or specced. Ultimately they provide a better user experience, and in my eyes, that’s what matters most, because without users, WordPress doesn’t exist. :-)

        It’s half the reason we blog, right?

        Heck yeah! I love the discussion too. It’s always good to present sound arguments where you can be sharpened by other people that far exceed your knowledge and abilities, and I definitely consider you to be one of those people. :-)

        1. You can make this argument too with WordPress. If you start out developing with WordPress, you don’t know PHP.

          You may not know PHP (or you may), but you can likely pick it up. The same can be said about CoffeeScript and JavaScript or jQuery and JavaScript or Rails and Ruby on so on. Platforms, frameworks, and all that jazz create this regression argument that I’ve long since bowed out of.

          To your point about Genesis (or Hybrid Core and any true framework – because I think that word is overused), that’s different than a theme introducing its own custom hooks. If you opt to go with a framework, then you’re opting to go with an abstraction layer on top of WordPress that you’re voluntarily locking yourself into. I think Frameworks get a pass on custom hooks because of the nature of what they are – Frameworks and frameworks have their own API. It’s expected.

          Themes on the other hand, don’t don’t get that pass. Themes are not to be equated with frameworks and shouldn’t introduce their own custom hooks when WordPress’ default functionality provides exactly what’s needed to introduce whatever change is needed.

          Custom Hooks aren’t utilizing the core functionality of the appliction – unless we’re misunderstanding one another – a custom hook is a hook that WordPress doesn’t define within its API (as listed in a previous comment). It’s can’t be part of the core functionality of the WordPress application if it’s not part of the API.

          Twentytwelve takes advantage of apply_filters which isn’t deviating from the API. My main gripe is about themes that define certain custom functions in their code that basically result in other developers coming to modify that theme by doing something like the following:

          if( this_theme_hook_exists() ) { 
            // Foo
          } elseif( this_theme_particular_hook() ) {
            // Bar
          } else {
            // Baz
          } 
          

          That’s doing it wrong, but using things like apply_filters or leveraging actions and filters as defined by WordPress is the correct way to go about doing it. Stanardizing something like that with a clear list of what’s allowed is one thing, but these theme-level “hooks” which result in massive if/then/else blocks aren’t hooks, but they’re presented as such.

          Finally, this I can get behind:

          What we can do is promote the correct way to create child themes and promote the correct use of hooks and filters, standardized or not. I think there is a lot of movement around that type of thinking in WordPress, and I am behind that 100%.

          Promotion of how to develop themes so that they are child theme compatible, when and how to use child themes, how to write hooks (that is, actions and filters) using apply_filters but not some of the way other authors are doing it.

          That’s my gripe.

    2. The problem with standardizing hooks and filters for Themes is just that – you have to standardize hooks and filters for thousands upon thousands upon thousands of innumerable combinations of theme layouts, styles, designs and implementations. There is no possible way that you can reliably code in that scenario and expect the same type of output across the board. In fact, that would be incredibly frustrating as a developer to never know if the “standardized” hook you are using will actually function as it is supposed to.

      I disagree. In fact, the very concept of template-location-specific hooks allows for consistency of output, and allows for the beauty of the implementation. A Plugin developer doesn’t have to guess where or how a Theme developer outputs after-post_content content; instead, the Theme developer fires the standard tha_entry_after action in the template location appropriate for the given Theme design/markup, and the Plugin developer simply adds a callback to the standard tha_entry_after template hook, and his content, intended to be output after the post content, will be output properly.

      To put it bluntly, the average theme author isn’t smart or savvy enough to know how to do it right – and for something like this to work, it has to be done right.

      I firmly believe that every single Theme developer that currently defines custom template hooks for their Themes will understand exactly how to implement a set of standard template hooks. Adding that compatibility layer is dead-simple, as it requires nothing more than firing the standard action hook within the pre-existing, custom action hook.

      As for Themes that don’t currently implement template action hooks: that’s where the Theme Review Team and the Theme Review Guidelines can help, by recommending implementation of the standard template hooks as a best practice, and helping to educate Theme developers regarding how to implement them.

      I’m all for using them as well, but what happens when you want to change something simple like the order of post meta for a post? Not that performance is going to be affected, but that means you have to copy over the whole flow of code just to change the order of something simple. Again, it may not be standardized, but it is definitely more efficient have some sort of custom filter to alter that data.

      A filter is *exactly* the most efficient, flexible approach in this case. And the Theme Hooks Alliance is currently discussing the feasibility of implementing standardized filter hooks, to complement the standardized action hooks.

  4. Trying my comment again!

    Just saying that I agree with the idea of writing cleaner code. Hooks can make things very confusing when it comes to actually modifying themes.

    Hooks in themes end up annoying me more than anything else.

  5. I’m glad someone is addressing this problem on their design blog. I am finishing up a review and testing of over 18 various wordpress frameworks and themes. And personally, I am disgusted by the way theme developers are using custom hooks. It is an absolute atrocity because they are obvuscating good design practices. The point of WordPress themes is that templates and style.css make it a snap to look at a source page and understand what’s going on and make changes. The heavy use of snap-in hooks is encouraging people to spread out code through multiple files and make it NOT CLEAR what’s going on. This is what a lot of us call “over-engineering”.

    If someone needs to do site-wide customization where they present content with heavy conditions, they should write their own hooks into their templates and create their own plugin or functions.php function to do it. These fancy frameworks that try to give you every hook under the sun are overkill that are doing harm to WordPress best practices.

  6. Greetings !! as you mentioned, just the quick “great post” types, in this theme can we use seo plugins or their is any kind of admin panel where i can set meta tag into my website.. graphic in this theme look stunning.

  7. I think its better practice to insert custom hooks in the parent themes template files and then hook into those locations using custom functions in a child theme rather than modify template files in any theme.

    1. I agree with you that if you’re doing to place hooks in a theme, then it should be in the parent theme so that child themes can hook into them, but it’s the custom hooks that get me.

      There are a documented set of hooks that WordPress provides and I’m more of a fan of sticking to what’s available than deviating too far from the beaten path. It’s introducing something that developers don’t expect and it deviates from the core functionality of WordPress.

  8. I really don’t agree with any of the 3 points made…

    About #1: Hooks are hooks, it doesn’t matter what they’re in. It’s just a standard event handling convention WordPress has adopted (it fits right in with many signal/slot event handling libraries, and really isn’t any different than MediaWiki’s hooks either[1]). Anything that needs an event handling system should use the same convention, and themes need to provide hooks just as much as they need them in core themselves in order to maintain that same level of extensibility plugin developers expect in core. The custom hooks in themes are used for the same definition of what a hook is. WordPress tries to define them in the codex for convenience, but nothing about them restricts their use to core and plugins. The WordPress definition you used is really only providing some primary use cases. I don’t even take stuff I read off of Wikipedia that literally most of the time, it’s still user-contributed content.

    [1] MediaWiki even has an equivalent generic custom theme hook that skins trigger themselves too.

    About #2: A child theme is still a *theme*, not a plugin. The custom hooks being used are there for plugins to extend, and the functionality they are used for is the type that belongs in a plugin, not a theme. We still don’t advocate that developers include functionality that extends and modifies core in their themes, and that applies to a child theme just as well. Child themes are not the “appropriate alternative” to custom hooks in themes, nor do custom hooks negate the purpose of child themes.

    About #3: This practice isn’t damaging the community in any way. What is the purpose of having an extendable system for custom plugins and themes if either are bound by rules on what they can and can’t do (assuming it has nothing to do with common security practices or preventing serious performance problems anyway). It’s obviously working fine for many developers and shops or they wouldn’t be doing it. They aren’t doing it because they chose to once, and now they’re stuck with doing it for eternity. It’s also not even hurting anyone that isn’t using them even if they are using a theme that contains them (but even this would be acceptable in my opinion – if you don’t like it, you’re not being forced to use it).

    If a plugin is absolutely insistent that it’s only going to support themes that do, that’s their choice, we’re certainly not lacking completely free alternative plugins in the community. However, it’s not like it isn’t possible for a plugin to detect that a theme doesn’t support this, and offer fallbacks that use “the_content” or other inappropriate hooks as a “next best guess” too. There’s no vendor lock-in here, even if WordPress never adopted one of these standards.

  9. A bit late to the conversation (as I always am, it seems), but if the dichotomy is “customize theme via child theme” vs. “customize theme via hooks,” I can’t help but ask, “why not both?”

    Child themes are nice if you’re making changes to the regular output of a theme — it’s markup, it’s styling, etc. — or for adding template files (such as tag-tagname.php) that are unique to your site, a custom CSS file for your site, or whatever else… but if all you want to do is add, say, a banner after the header of your theme, which is easier?

    A) Create a custom theme. Copy the header file to your theme. Add your banner into the appropriate location. Keep your header file up-to-date with all future markup changes in your parent theme, to ensure no styling breaks.

    OR

    B) Create a private site plugin. Add your banner as an action to the appropriate hook. Set it and forget it.

    Yes, themes may have proprietary hook names, but that’s okay — no standardized list can encompass all possible hook locations given that themes can very significantly. Done with versatility in mind, hooks can support both “standard” hooks (i.e., Theme Hook Alliance) as well as proprietary ones, such as in Flat.

    Ultimately, child themes are great, but so are hooks. Each serves their own purpose. Themes that are designed with both means of customization in mind empower their users to customize however they feel comfortable, using the most efficient means for whatever they are attempting to do.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.