Demystifying the WordPress Hook System

Share this article

Demystifying the WordPress Hook System

If you’ve been developing websites with WordPress (including plugin and theme development) chances are you’ve heard these terms: Hooks, Actions, and Filters. These are part of the Event-driven Architecture Pattern, which WordPress uses.

Are you new to WordPress development or finding it difficult to understand the basic concepts? I can’t recommend highly enough Simon Codrington’s Introduction to WordPress Plugin Development tutorial. He did a great job of explaining Actions, and Filters.

In this tutorial, I’ll be demystifying the WordPress hook system, leaving no stone unturned. Without further ado, let’s get started.

Hooks, Actions, Filters. What Are They?

‘Hooks’ are basically events triggered by WordPress core, themes and plugins at various stages of their execution or interpretation by PHP. When these events are triggered, all the functions and/or class methods hooked or attached to them are executed in their correct order.

Hooks come in two forms, Actions and Filters. While the former is used to add and remove features or functionality at various stages of process execution, the latter modifies the behavior of various features and implementations. Don’t worry if you still don’t understand. You will when we start seeing some code examples below.

Importance of the Hook System in WordPress

The importance of the hook system in WordPress is simply extensibility. It makes it possible to add and remove features, as well as tweak/modify the implementation of features in WordPress core, plugins and themes.

When you write extensible plugins and themes, you make it possible for other developers to improve and extend them without ever editing the core source code.

WordPress Hooks

Allow me to cite an example. Unlike most payment gateways, my 2Checkout Payment Gateway for WooCommerce plugin does not include an icon displaying the supported credit card types on the checkout page because I felt it is unnecessary. But you know what; I added a filter in case a user feels otherwise.

It just so happened that we received a support request from a customer requesting for the inclusion of the icon. We were able to provide a code snippet to the customer that hooks into the filter and includes the icon.

Delving into the WordPress Hook System

At various stages of WordPress execution, a large number of events are triggered commonly using the do_actions() and apply_filters() PHP functions. These events can be subscribed or hooked to via add_action() and add_filter().

Please note the use of the word ‘commonly’. There are other ways events can be triggered. We’ll explore that in the second part of this tutorial.

Below is an example of an action in a plugin. This action is fired after a successful user registration in my ProfilePress user registration plugin.

/**
 * Fires after a user registration is completed.
 *
 * @param int $form_id ID of the registration form.
 * @param mixed $user_data array of registered user info.
 * @param int $user_id ID of the registered user.
 */
do_action( 'pp_after_registration', $form_id, $user_data, $user_id );

During WordPress execution, all the functions hooked into this action will be processed.

An example of a filter hook is the_content in WordPress core which filters every posts contents.

    /**
     * Filter the post content.
     *
     * @since 0.71
     *
     * @param string $content Content of the current post.
     */
    $content = apply_filters( 'the_content', $content );

Take Note

In do_action(), the first argument is the name of the action hook and subsequent arguments are variables available to functions that hook into the action.

And in apply_filters(), the first argument is the name of the filter hook, the second is the data or value on which the functions hooked to the filter are modified or applied. Subsequent arguments are variables/values available to functions that hook into the filter.

Don’t worry, all this will make more sense as we examine code examples.

Action Hook Examples

Example #1

Taking my ProfilePress plugin’s pp_after_registration action for a spin; let’s say we want to implement a feature where users will receive an SMS (via an assumed messaging service called Dolio) welcoming them to your website immediately after registration. Our function hook could be in this form:

add_action( 'pp_after_registration', 'send_users_welcome_sms', 20, 3 );

function send_users_welcome_sms( $form_id, $user_data, $user_id ) {
    global $service_locator;

    $username    = $user_data['username'];
    $firstName   = $user_data['first_name'];
    $lastName    = $user_data['last_name'];
    $phoneNumber = $user_data['phone_number'];

    $text = <<<SMS_CONTENT
Hello $firstName $lastName, Welcome to SitePoint. "\r\n"

User ID: $user_id "\r\n"
Username: $username "\r\n"
Password: The password you sign up with "\r\n"

SMS_CONTENT;

    $dolio = $service_locator->get( 'dolio_sdk' );
    $dolio->phone_number( $phoneNumber );
    $dolio->sms_content( $text );
    $dolio->send();

}

The third argument of add_action in the code above is the hook priority which specifies the order in which the function hooked to pp_after_registration action will be executed. Leaving this empty will default to 10. While the fourth argument specifies the number of arguments the function hook will accept. Default to 1 if empty.

Assuming I left out the fourth argument, thus defaulting to 1, the $user_data and $user_id variable will be null because we only told the function to accept just one argument.

Example #2

WordPress includes the following action hooks — wp_head and wp_footer — that are both triggered in the head tag and before the closing body tag on the front end respectively.

These hooks can be used to display script and data at those strategic locations.

Let’s check out some code examples.

The code below uses wp_head to include Google’s site verification meta tag to the header of the WordPress front end.

add_action( 'wp_head', 'google_site_verification' );

function google_site_verification() {
    echo '<meta name="google-site-verification" content="ytl89rlFsAzH7dWLs_U2mdlivbrr_jgV4Gq7wClHDUJ8" />';
}

All hook functions will be anonymous in lieu of the named function to avoid unnecessary repetition of function’s names. For example, the code for Google site verification Meta tag above will now become:

add_action( 'wp_head', function () {
    echo '<meta name="google-site-verification" content="ytl89rlFsAzH7dWLs_U2mdlivbrr_jgV4Gq7wClHDUJ8" />';
});

The code below uses wp_footer to add JavaScript in the footer area of WordPress front end.

add_action( 'wp_footer', function () {
    echo '<script type="text/javascript" src="http://example.com/wp-content/plugins/site-specific-plugin/hello-bar.js"></script>';
});

Enough of the action hooks code example, let’s check out filters.

Filter Hook Examples

Example #1

Say we are developing an ad inserter plugin that will programmatically insert ads before and after every post content, the the_content filter is what we need.

The code below includes the text ‘We love SitePoint’ before and after every post content.

add_filter( 'the_content',
    function ( $content ) {
        $text = sprintf( '<div class="notice alert">%s</div>', __( 'We love SitePoint', 'sp' ) );
        $content = $text . $content . $text;
        return $content;
    });

Code explanation: the content of $text variable is the same as <div class="notice alert">We love SitePoint</div> albeit internationalized so that it can be localized. Confused? Please take a look at my tutorials on WordPress i18n and l10n.

Mind you, the function parameter $content, is the variable that supplies the post content.

We then append the custom text before and after the post content, save the resultant data to $content and subsequently return it.

Note: all filter hook functions must return the variable parameter after manipulation or modification.

Example #2

Another filter example we’ll look at is the_title. Below is how it is defined in line 158 of wp-includes/post-template.php.

    /**
     * Filter the post title.
     *
     * @since 0.71
     *
     * @param string $title The post title.
     * @param int    $id    The post ID.
     */
    return apply_filters( 'the_title', $title, $id );

The code below modifies only the title of a post with ID 5978 by appending - WeLoveSitePoint to it. This is possible thanks to the $id argument.

add_filter( 'the_title', function ( $title, $id ) {
        if ( $id == '5978' ) {
            $title .= ' - WeLoveSitePoint';
        }

        return $title;

    }, 10, 2 
);

Conclusion

The reason WordPress continues to be the leading content management system is because of its extensibility.

The WordPress Hook system has made it possible for WordPress to be transformed into powerful web applications, whether that be an ecommerce store with WooCommerce, a forum with bbPress or even a social networking site with BuddyPress.

In Part 2 of this tutorial, I will sharing some cool and little known facts about the hook system in WordPress such as how to: use them in a class, hook static and non-static methods to actions and filters, use namespaces, its caveats and solutions and a whole lot more. So stay tuned and happy coding.

Frequently Asked Questions (FAQs) about WordPress Hook System

What is the difference between action hooks and filter hooks in WordPress?

Action hooks in WordPress allow you to insert custom code at specific points (or actions) in your code. For instance, you can use an action hook to add a piece of code that runs whenever a post is published. On the other hand, filter hooks allow you to modify data before it is sent to the database or the browser. For example, you can use a filter hook to change the default “read more” text in WordPress posts.

How can I create a custom hook in WordPress?

Creating a custom hook in WordPress involves two steps. First, you need to define the hook using the do_action() function for action hooks or the apply_filters() function for filter hooks. Then, you can add functions to your custom hook using the add_action() or add_filter() functions. Remember to place your custom hook in the appropriate place in your theme or plugin file.

Can I remove a function from a hook in WordPress?

Yes, you can remove a function from a hook in WordPress using the remove_action() or remove_filter() functions. You need to specify the name of the hook and the function you want to remove. Note that the priority and the number of arguments should match those used when the function was added to the hook.

How can I change the priority of a function in a hook?

When adding a function to a hook using the add_action() or add_filter() functions, you can specify the priority of the function as the third argument. The default priority is 10, and functions with lower numbers are executed first. If you want to change the priority of a function, you need to remove it from the hook and then add it again with the new priority.

What are some common uses of hooks in WordPress?

Hooks in WordPress are used for a wide range of tasks, such as customizing the appearance of your site, adding custom functionality, modifying the default behavior of WordPress, and integrating with third-party services. For example, you can use hooks to add social media sharing buttons to your posts, change the default “read more” text, or send a notification email when a new comment is posted.

How can I find the available hooks in WordPress?

WordPress has hundreds of action and filter hooks that you can use in your theme or plugin. You can find the available hooks in the WordPress Codex or the WordPress Developer Resources site. Alternatively, you can use a plugin like “Simply Show Hooks” to display all the hooks running on your current page.

Can I use hooks in my child theme?

Yes, you can use hooks in your child theme to add or modify functionality without changing the parent theme. This is a good practice because it allows you to update the parent theme without losing your customizations.

What is the difference between add_action() and do_action() in WordPress?

The add_action() function in WordPress is used to add a function to a specific action hook. This function will be executed when the hook is triggered. On the other hand, the do_action() function is used to trigger (or “do”) an action hook. This will run all the functions that have been added to the hook.

Can I use hooks in my custom post types?

Yes, you can use hooks in your custom post types to add or modify functionality. For example, you can use the save_post action hook to perform a task whenever a post in your custom post type is saved.

How can I debug hooks in WordPress?

Debugging hooks in WordPress can be done using various methods. One common method is to use the error_log() function to log the output of your hook functions. You can also use a debugging plugin like “Query Monitor” to view the hooks running on your current page.

Collins AgbonghamaCollins Agbonghama
View Author

Collins is a web developer and freelance writer. Creator of the popular ProfilePress and MailOptin WordPress plugins. When not wrangling with code, you can find him writing at his personal blog or on Twitter.

ChrisBplugin developmentplugin tutorialWordPressWordPress hooksWordPress Plugin Development
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week