You want to remove some callback hook in WordPress. You keep trying, but it’s not working. Argh, why isn’t it working? Did you know that timing is important? There are two (2) common timing mistakes when removing (or attempting to remove) a WordPress callback hook. Let’s explore these timing mistakes and then give you some strategies to master the remove process every single time.
Make sure you know what the heck a WordPress hook is. You’ll hear terms like action, filter, hook, and event. In a nutshell, a hook in WordPress is a callback that is registered to some event name. It allows you to run your code at a specific point in the web page request cycle. In other words, it lets you hook into WordPress Core, a plugin, or theme when some event happens.
Timing matters in software. Starting with the first file on line 1, the code runs in a specific order, as defined by the code itself. Line-by-line it runs. Keep this in your mind.
Timing matters in software! With hooks, you need to figure out when to add and when to remove them. Else, you’re going to be frustrated when it doesn’t do what you want.
Two (2) common mistakes are attempting to remove an action or filter callback hook too early or too late. Whoops, doing it too early and the callback hook hasn’t been registered yet. Doing it too late and the event has already fired, meaning the callback already ran. Timing matters.
You need to remove the callback hook after it’s been registered but before the event fires.
To remove a #WordPress hook, do it after it's been registered but before the event fires. Share on XMistake 1: Removing the hook too late
A common mistake is attempting to remove the action or filter callback hook too late. Whoops, the event has already fired. It’s too late to remove that behavior.
Whoops, the event already ran. It’s too late to remove the hook.Stop and think about what I just said. Why is this important? The callback hook, that function you’re trying to remove, runs when the event fires. Right? Therefore, if the event has already occurred, doing a remove_action
or remove_filter
isn’t going to do what you want. Why? The code already ran. It’s too late.
In order to remove a callback hook, you have to do it before the event fires.
How do I determine when to remove the callback hook?
Here’s an approach strategy for you:
- Identify the event’s name and type of event.
- Find where the event fires.
- Identify the code that fires it.
- Find out when that code runs in the web page request cycle.
- Write your remove to occur before that code.
1) Identify the event’s name and type of event
Look at the callback hook you want to remove or replace. The first parameter is the event’s name. The function it uses to register that callback sets the type of event.
For example, let’s say you are using the Genesis framework and want to remove the byline under the post title (i.e. that post metadata that has the date, author, and comments). Here is the line of code in the framework:
add_action( 'genesis_entry_header', 'genesis_post_info', 12 );
What type of event is it? Look at the construct. It’s using add_action
. The “add” means to register this callback hook for the given event name. Then “action” means it’s an action event.
Why is it important to know the event type? Because it helps you build your global search. You know that it will use either do_action
or do_action_ref_array
to fire (run) the event.
Next, what is the event name? It’s the first parameter. For our example, the event name is genesis_entry_header
.
2) Find where the event fires
Next, you need to find where the event name fires (runs) in the code. How do you do this? Do a global search for it. Use the information you discovered in the previous step.
Using our example, what would your global search be? Let’s walk through it:
- It’s an action event. Therefore, it will run when either
do_action
ordo_action_ref_array
runs. You are looking for either of these constructs. - The name of the event is
genesis_entry_header
.
Let’s start with searching for the most popular one, i.e. the do_action
. Your global search then will be:
do_action( 'genesis_entry_header'
Tip: Leave it open ended just in case there are arguments declared.
3) Identify the code that fires it
Once you find where it fires, scroll up until you find the function that it runs within. In the above step, the global search found it in the file genesis/lib/structure/loops.php
in the function genesis_standard_loop()
. That was easy.
4) Find out when that code runs in the web page request cycle
Now it’s time to discover when the function runs. The degree of difficulty here is completely dependent upon the code and your ability to backtrace it. But let me give you a methodology.
Continue the approach above. Find each occurrence of where the function is called. Then look at that spot and figure out when it happens.
Big clue coming right now. Ready? You just need to know a general idea of when and not the specific of it. You’re trying to figure out a spot in the overall sequence to put your remove code. Think big picture here.
Let’s use our example.
Starting where the do_action
is, you identified the function that it runs within. Right here and now you can make an educated guess of when this function runs. Right? Think about it. The function is called genesis_standard_loop()
. WordPress runs the Loop to loop through each of the posts, build them, and render them out to the browser.
To discover when it runs, you can look at the function itself and see that it is the main loop for the web page. That’s one technique. The other is to continue backtracing until you find the main template file that calls it.
5) Write your remove to occur before that code
At this point, you know when the firing event occurs. Your strategy now is to pick a time in the sequence before this event fires. In our example, the event fires (runs) in the Loop. Okay, when would you want to remove the callback hook then? Before the loop starts.
You could use the event loop_start
as a trigger point or any other event that happens before the genesis_entry_header
runs. In Genesis, you have a lot of options such as loop_start
(which comes from WordPress Core), genesis_before_while
, genesis_before_loop
, and many others.
The main point here is: pick a time in the overall sequence that occurs before the event fires (runs).
For our example, you might do:
add_action( 'loop_start', 'remove_post_byline' ); | |
/** | |
* Remove the post metadata byline from the HTML markup. | |
* | |
* @since 1.0.0 | |
* | |
* @return void | |
*/ | |
function remove_post_byline() { | |
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 ); | |
} |
“I have had memberships with Treehouse, WPSessions, First Version, and Pippin Williamson’s site. They all provided value to my career, but Know The Code has helped me attain a new level.”
Go Pro and grow your expertise and career.
Mistake 2: Removing the hook too early
Too early – it hasn’t been registered as a callback yetJust like with attempting to remove it too late, too early is also problematic. Why? You are removing a callback that hasn’t been registered yet. It’s not in the event registry, i.e. the global variable $wp_filter
.
Think about how the event (hook) system works in WordPress:
- You pre-register a callback using
add_{action or filter}
. - The callback is then added to the registry for the specified event name.
- Then when the event fires, each callback runs in order, one-by-one.
- When all have run, control returns back and the event is done.
Look at step one. If you attempt to remove the callback before its add_action
or add_filter
runs, it’s not in the registry yet. Running remove_action
or remove_filter
won’t do anything. Why? It’s not in there yet.
Let’s do a visualization exercise. Let’s say you are a WordCamp volunteer. The team lead asks you to unregister Sally, as she has a conflict and won’t be able to attend the event. You go into the registry where everyone signed up and bought a ticket. But Sally has registered yet. She’s not in the registry for this WordCamp. You can’t remove her because she’s not in there…yet. Now picture the scenario where a few hours later, Sally registers and buys her ticket. You don’t know this. When you checked, she wasn’t in there. She registered later, meaning after you went in to remove her.
Keep this thought process in your mind. Let’s relate it back to WordPress. If you try to remove a callback that doesn’t yet exist in the registry, what happens? Once the code that registers it runs, bam, that callback is registered. You tried to remove it too early. Whoopsie.
How do I determine when to remove the callback hook?
The approach is very similar to finding when the event fires, except that you are making it “add”-centric. Huh, you are looking for when the registration occurs. Here is a strategy for you:
- Identify where the callback is in the codebase.
- Identify the code that runs it.
- Find out when that code runs in the web page request cycle.
- Have your remove occur after that code.
1) Identify where the callback is in the codebase
You already should know what you want to remove. Now it’s a matter of finding that line of code in the codebase. Start with what you know. You know the event name and callback. Do a global search and find that line of code.
Continuing with the same example above, you want to remove the post byline in the Genesis framework. Looking in the framework’s codebase, the line of code that adds the callback and registers it is in genesis/lib/structure/post.php
add_action( 'genesis_entry_header', 'genesis_post_info', 12 );
2) Identify the code that runs it
The next step is to identify what code is responsible for running the add. Start at the line of code where the add_{action or filter}
is (i.e. from the previous step). Look at the code. Is it wrapped within a function, method, or closure? If no, it’s at the root of the file. If yes, then scroll up and find the function that contains it.
3) Find out when that code runs in the web page request cycle
Next, you need to discover when the code runs. Why? Because you need to find a starting point in the cycle to ensure your remove line of code occurs after this point.
If it’s in a function, then you need to backtrace to see when that function runs. You are searching for when in the web page request cycle this line of code runs. Use the same strategy I gave you above and backtrace to find when it occurs. Remember to think big picture here.
For our example, the add line of code occurs in the root of the file. Therefore, when the Genesis framework loads, this file loads.
What does that tell you? Think about it. It tells you that the callback is registered to that event name when the framework loads. That’s very, very early in the cycle.
4)Have your remove occur after that code
Now you know when the add occurs in the web page request cycle. Knowing the “when” allows you to select the right timing for doing your remove code.
For example, let’s say that the callback gets registered after the main content area starts being built. You can then select an event that happens after that point to run your code.
In our case, the code runs when the Genesis framework loads. Therefore, in your child theme, you can do the remove after the framework loads up. How you do this depends upon if you are running your child theme first before loading the framework.
What do I mean by that? Most Genesis child themes use the strategy of loading the framework first and then loading up all of the child theme features, files, and functionality. The first lines of code in the functions.php
file are:
//* Start the engine include_once( get_template_directory() . '/lib/init.php' );
Therefore, within the child theme, it’s safe to just do the remove after this line of code:
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 );
However, let’s say you build your child themes like I do. The child theme loads first and then the parent loads. In this case, you’ll need to select a time to do the remove. A popular approach is to do it with genesis_meta
. But you have plenty of options such as loop_start
.
The main point here is: pick a time in the overall sequence that occurs after the callback is added (registered).
A shortcut strategy if all else fails
What if you can’t find the right timing? How else can you remove the callback hook without having to explore the entire codebase? You can use a shortcode strategy.
- Register a callback to the event name
- Make the priority number greater than the add
- Then put the remove code within the callback
As an example, if the “add” code is this:
add_action( 'genesis_entry_header', 'genesis_post_info', 12 );
then you write this code:
add_action( 'genesis_entry_header', 'remove_post_byline', 9999 ); | |
/** | |
* Remove the post metadata byline from the HTML markup. | |
* | |
* @since 1.0.0 | |
* | |
* @return void | |
*/ | |
function remove_post_byline() { | |
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 ); | |
} |
A word of caution
This technique can be confusing and is less readable. It’s a hack. Therefore, only use it as a last resort. Otherwise, anyone else who comes along may be confused by it.
Wrap it Up
Go ahead and use these techniques. It’s time for you to master callbacks, hooks, and events and get your work done without all the frustration. Let me know how it works for you in the comments below.
Patrick van Raalten says
Thank you very much for this excellent article! After hours of searching and frustration I found your article and solved this nagging problem! Bravo!
Marcus says
Great article on the topic hook removal topic, keep the good work.