I am trying to understand how hook methods work in WordPress. I understand that when do_action is called WP looks for all registered listeners and invokes them according to set priority.

How does WordPress core collect all registered hook methods in different files? For example, I have declared add_action for wp_head in my footer. Will it be executed? So it seems that WordPress should collect all data iterating over all files?

Please explain this.

  • I think it will not be executed, the declaration in the templates files is too late. Conversely, the functions.php file and the plugins files are loaded before the template, so the hooks have to be declared in them – Pierre Jun 18 '16 at 13:11

Your analogy here is partially correct, but incomplete:

I understand that when do_action is called wp looks for all registered listeners and invokes them according set priority.

You need to consider what happens when you call add_action. WordPress never searches for the add_action statements, it has those in a list. When you call add_action, it updates a list of callbacks to call when that action happens.

With this in mind, it's more useful to use an events analogy.

  • do_action( 'init' ) Fire the 'init' action
  • add_action('init', 'myfunction' ) When the init event happens, call myfunction
  • function myfunction() {} Ah the init event happened

The events analogy helps enormously when understanding how actions and filters work, because there's a whole class of problems that happen when you don't understand related to timing.

Lets take your example of calling add_action in the footer for the wp_head action. wp_head fires when wp_head() is called, which should happen in the header between the <header> tags. If we try to add an action in the footer, then it will be added, and the next time wp_head() is called it will fire. But wp_head has already been called, it's too late. It's like asking a child "remember to pack your bag before the party" just after the party has ended.

With this in mind I have some general rules and recommendations that would act as heuristics for more maintainable code:

  • Put all code inside functions that fire on events. init, after_theme_setup, wp_head, and admin_init should cover most of it
  • The only code outside of a hook or filter Would be template files, and the initial add_action calls
  • Don't add filters and hooks inside templates, do them in functions.php or a plugin, or if those files use include or require statements for an includes folder

There are some situations you'll want to break those rules, usually to prevent recursion when saving things, etc, but those should be rare exceptions. Experiment and see what works, and look at this post that shows which actions fire when, and what's safe to use at those times

A final note, actions and filters are the same thing. Internally they're treated the same, but there are some important differences if you want things to work well:

  • Actions do things
  • Filters modify things
  • Actions don't need to return anything
  • Filters are passed what's being 'filtered' as the first argument, and always return it or a modified version
  • Filters are called a lot, so never do heavy work in filters, it will slow things down massively, only modify, doing work is what actions are for
  • Be wary of hooking into the translation and escaping filters, it can be dangerous, and has a major impact on performance as those are the most commonly called filters
  • There is an especially dangerous action/filter called all, that will fire for every filter and hook. Useful sometimes for debugging, but I'd recommend using a plugin such as query monitor instead.
  • Great answer !! Thank you. I didn't understand the order of execution, now I got it thank you. – Ptzhub Jun 18 '16 at 14:20

All your actions belong in your functions.php, assuming that you are building a theme. It is here that you add actions to certain events in your templates.

Now, once it has read functions.php WP has a list of actions it is supposed to undertake at certain points in your theme templates. There are several predefined action hooks, such as wp_head() and wp_footer(), which are shorthand for do_action('wp_head') and do_action('wp_footer'). They are defined, so plugins have standard places where they can add their action. You can also define your own action hooks with do_action.

So, for instance, if you want to add the same image at the end of every post, you would define in your functions.php the following action:

add_action ('my_post_image', 'generate_my_post_image');
function generate_my_post_image () {
    echo '<img src="path_to_my_image">';

Then in your index.php you would have:

while (have_posts()) {
    ... generate your post ...
    do_action ('my_post_image');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.