WordPress Actions and Filters: What's the Difference?

Action and filter hooks are a fundamental part of the various WordPress APIs. Without them you're limited as to what you can do in your themes and (especially) your plugins.

But sometimes it can be easy to confuse the two, especially in the cases when WordPress has both an action hook and a filter hook with the same name.

In this article I'll define action and filter hooks and describe the difference between them, and I'll demonstrate how to use them in your themes and plugins. I'll also give some examples of when you might use each.

When you're adding action and filter hooks to your code (or you're hooking functions to them), it helps to understand how actions and filters are called by WordPress and what happens in what order. I won't cover that in detail here as we have another tutorial that does that job.

Definitions and Differences

Let's start with some definitions. I'll define action and filter hooks and functions too, so you can see the difference between them all.

Functions

Functions are the first thing most people work with when they're learning WordPress development; if you've added code to your theme's functions.php file, then you'll have written a function.

Functions specify how something will happen. You code a function to query data, to output content, or to perform many other tasks. You can call (execute) functions directly in your theme's template files, or you can hook them to action or filter hooks. Functions can also include template tags such as conditional tags, to specify when the function should apply.

I'll show you the different ways to execute functions later in this article.

Action Hooks

Action hooks (or actions) are triggered when something takes place, such as loading a page, a user logging in, or a custom action that you define in your theme or plugin.

You can add your own action hooks using the do_action() function, which I'll demonstrate shortly. Any functions you hook to that action will then run at that point in the code.

Filter Hooks

Filter hooks, or filters, control how something happens or change something that's already being output. You could use a filter to output metadata in a specific format, to override text output by your plugin, or to prevent something from being displayed at all.

You add filters in your code using the apply_filters() function, which I'll demonstrate shortly. As the word 'apply' indicates, you apply filters to existing code, whereas an action you create using do_action() is empty until you hook functions to it.

Using Functions, Actions, and Filters

Let's take a look at some examples demonstrating how you use each of functions, actions, and filters. First, we'll look at using functions directly in your code without attaching them to a hook.

Calling Functions Directly

Here's an example of a function that's called directly in a template file. In my client sites I add a colophon in the footer, which includes copyright information. Here's the function:

This function is pluggable as I use it in a parent theme; if I then create a new function with the same name in my child theme, that will override this function. Note that the function includes another function, compass_colophon(), calling it directly in the code.

This function is in the functions.php file of my parent theme. I can call it directly in the footer.php file of my theme, like so:

This outputs the code in the function at the point in my theme where I call it. You can also pass parameters to your functions, which are then used inside the function.

As I'll demonstrate shortly, this function could also be hooked to an action or a filter.

Hooking Functions to Actions

Rather than calling that colophon function directly, I'll have more flexibility if I attach it to a hook.

Creating Action Hooks

Instead of calling the compass_colophon() function in my footer file, I can add an action hook at that point in the footer.php file, by adding this:

The do_action() function has one mandatory parameter, which is the name of the action. You can also optionally add arguments to it.

Hooking Functions to Actions

So now instead of calling my colophon function, I need to hook it to my new action hook. In my functions.php file, I add this with my function:

This hooks my function to the compass_in_footer action, which means that the code inside my function will run at the point in the code where the action has been placed. The first parameter is the name of the action hook, and the second is the name of my function.

An advantage of doing it this way is that you can hook more than one function to the same action, and you can set the priority so they fire in the order you want them to.

So let's say I have another function I want to hook to my compass_in_footer hook, called compass_smallprint(), which contains some more small print:

You can see here that I've added a third parameter to my add_action() function, which is the priority. The default priority is 10, which will be applied if you leave this blank. So because I haven't set a priority for my compass_colophon() function, setting 20 for the compass_smallprint() function will make that function run after the compass_colophon() function.

Unhooking Functions From Actions

Sometimes you want to stop a function from running, and you can't override it because it's not pluggable. If the function has been hooked to an action hook, then you can do this using the remove_action() function.

So if I want to prevent my compass_smallprint() function from running, I unhook it from the compass_in_footer action like so:

The remove_action() function has three parameters: the name of the action hook, the name of the function, and the priority with which the function was originally hooked to the action. You must include the priority for this to work.

You can also unhook all of the functions from an action if you want to prevent them all from executing. Be careful when doing this, as there may be functions you're not aware of hooked to your action.

To do this, use the remove_all_actions() function:

Adding a priority number as the second parameter only removes the functions which are hooked to that action hook with the priority you've specified, which gives you more control.

Hooking Functions to Filters

You also have the option of hooking your functions to filter hooks. You do this when you want to alter or override some existing code. When you create the filter hook (using the apply_filters() function), you wrap that around code in your theme or plugin, which is then altered by any filters attached to the hook.

This can be useful if you have theme or plugin options that you want to override a default setting, or if you're creating a parent theme that may have elements overridden by a child theme.

Creating Filter Hooks

The apply_filters() function has three parameters: the name of the filter hook, the value which you want to filter (i.e. the default value), and optional variables which you then pass to the functions hooked to the filter.

You can add a filter in your theme template files or inside a function that is hooked via an action hook. Let's take a look at both options.

Returning to my compass_colophon() function, I convert this to a filter by adding its contents to my footer.php file inside the apply_filters() function like so:

This outputs the code that I've set as the second parameter of my apply_filters() function.

However, I prefer not to add this directly to my theme template file, so I'll add the filter to the function that I'm already attaching via an action hook.

So I add the compass_in_footer action to my footer.php file using the do_action() function as demonstrated above, and then I create a function in my functions.php file which is hooked to that action and contains a filter:

This means that I can now override the default content in one of three ways:

  • by creating a new function called compass_colophon() in my child theme, which overrides the function in my parent theme as that's pluggable
  • by unhooking the compass_colophon() function from the compass_in_footer action hook and writing a new function which I attach to it in its place
  • by creating a new function which I then hook to the compass_colophon_filter filter hook, which overrides the value in my apply_filters() function

In real life you wouldn't need to have this many options, so it's more likely that you'd apply filters to part of the content in your function rather than the whole thing.

So I could create two filters, one for the copyright section and another for the credits:

Then I could either override the whole of my compass_colophon function by unhooking it or writing a new one in my child theme, or I could create a function hooked to the compass_copyright_filter or compass_credits_filter filter hook, to override each element individually.

Hooking Functions to Filters

To hook a function to a filter hook, you use the add_filter() function, which has two parameters: the name of the hook and the name of the function.

So to change the credits, I would write this function:

This overrides the value set in my original compass_credits_filter filter hook with the content of my new_credits() function, but keeps everything else in the compass_colophon() function the same.

You can also specify priorities when hooking functions to filters, in exactly the same way as with action hooks. Functions with a lower priority will be run first.

Unhooking Functions From Filters

As with action hooks, you can also remove functions from filter hooks. You do this using the remove_filter() function, which has three parameters: the name of the filter hook, the name of the function, and the priority, which is mandatory if a priority was set when the function was originally hooked to the filter.

So to remove my new_credits() function, I use this:

The code output would then revert to the value I specified in my original apply_filters() function. So if I wanted to remove the new_credits() function and have nothing appear in its place, I'd have to add a new function. I then unhook the first function and hook my new function like so:

Summary

Understanding the difference between action and filter hooks and being able to use both of them effectively will give your theme and plugin development a boost. In fact, without using hooks of at least one type, you can't write plugins at all, as the only way the code in your plugins is activated is via the action and filter hooks it's attached to.

This guide showed you how to add the same functionality using a function, an action hook and one or more filter hooks, along with techniques for removing functions from hooks and advice on when each technique is more useful.

As well as hooking functions to your own action and filter hooks that you create, you can hook them to the actions and filters provided by WordPress, such as the wp_head action or the body_class filter.

Tags:

Comments

Related Articles