The Pilcrow

A WordPress developer's thoughts on professional and personal development. Written by Karin Taliga

Why attention to hooks is important for a theme developer

If you are a theme developer, chances are that you know about or have heard about WordPress’ hooks and filters but are not always sure about why, when and how to use them.

Since WordPress is very forgiving about the structure of your theme, it is easy to just dump all your code into one big functions.php file that just keep on growing. This might work well for a time, but sooner or later you might run into problems.

This post is not about code structuring or how to split your file in logical chunks. Rather, it is about controlling when and where your code will be executed using hooks.

Let me give you an example.

Say that you have a bit of code that you only want to include in certain circumstances. And instead of adding that same bit of code to several page templates, you decide to include it through the functions.php using conditional logic.

Potential problem

You might be tempted to simply use the conditional tags like you would in any page template.

if( is_category() || is_page_template('listing') ) {
    // let's do this code
}

Only writing this code straight in your functions.php file will not work. The code above needs to be wrapped in a function and attached to an action hook.

Why?

Because the code will get executed whenever the file is included. And the theme file is included before the conditionals are set.

The WordPress load order

This all has to do with the load order of WordPress, the order in which files are included and the page request is setup. John Blackbourn has put together a super walkthrough of the initialization process of WordPress.

It’s a kind of pseudo-code writeup that goes through allt the steps taken when rendering a page. All the places where you see DO_ACTION in that walkthrough, that’s an action hook right there.

As you can see, the child theme files are included before the parent theme files, and much further down in the request part is when the global conditionals is_* are setup.

When your functions.php file is run, WordPress has no idea yet whether the request is for a page, category archive, a post or even a 404 error. Your if-statement will always be false, and the code will never be executed.

Action hooks to the rescue

By attaching the code to an action hook you can set the code to execute at a specific time in the load order. Specifically, at a later point where the conditionals exist and your code can function properly. In this case init – which is a commonly used hook – will also not work since that is too early in the loading process.

The hook I would recommend is simply called wp. This fires after the full environment has been setup but before the page template have been requested and the actual page has started to be assembled.

How to use an action hook

Instead of the code above, do this:

/**
* Do blah when we are on a category page or the listing page template
*/
function mythemename_categorycode() {
    if( is_category() || is_page_template('listing') ) {
        // let's do this code
    }
}
add_action( 'wp', 'mythemename_categorycode' );

You probably already use hooks

You probably know about and use hooks already. The most obvious example that comes to mind is enqueueing your stylesheet.

/**
* Enqueue stylesheet
*/
function mythemename_styles() {
    wp_enqueue_style( 'mytheme-style', get_stylesheet_uri() );
}
add_action( 'wp_enqueue_scripts', 'mythemename_styles' );

If you look at a theme like underscores, you see that almost all the code in it’s functions.php file is wrapped in functions that are attached to different action hooks. Hooks like after_setup_theme, widgets_init and so forth. This is a very good practice.

Make it a default to use hooks

Aim to have all your code wrapped in a function prefixed by your theme name. Attach all functions to a hook, unless they are meant to be called directly in template files.

This will prevent any unintended consequences and gives you full control over when and where your code is run.

Next Post

Previous Post

2 Comments

  1. Sebastian Jun 17, 2015

    i’ve been looking for an explanation just like this. thanks!

    although it is not working for what i’m trying to do with custom background image. i want the custom bg image only on the home page. here’s my code:


    function custom_bg() {
    if (is_front_page()) {
    echo "you are at front page";
    add_theme_support( 'custom-background' );
    }else{
    echo "you are NOT at front page";
    }
    }
    add_action( 'wp', 'custom_bg' );

    the echo part works, but the background doesn’t.

    the same thing happens even if i use after_setup_theme. which should always be false, no? but it’s not always false. do you know why?

  2. middlesister Jun 19, 2015 — Post author

    I don’t think you can add theme support conditionally in that way. Either your theme supports the custom background or it doesn’t.

    The add_theme_support call has to be on an early hook, the developer handbook recommends using after_setup_theme, just like you tried doing. I don’t know why the echo sometimes would work and sometimes not for you, but AFAIK the conditionals are not available in that hook.

    In order to just use the custom background on the front page, I think you vill need to use conditionals in a custom callback function. Justin Tadlock wrote a good article explaining how to make a custom callback function for your custom background.

    In that callback function, you can specify any css that you want output by WordPress when the user selects a custom background. Like, only using the custom background on the front page.

© 2018 The Pilcrow

Theme by Anders Norén