Site icon WP Smith

The Difference between do_action, add_action and add_filter

The Foundation: do_action

do_action creates the hook for things to hang. This is at the core of WordPress and even frameworks like Genesis and many other themes and plugins. do_action is the first domino in the chain of events with hooks. However, alone, it means nothing and does nothing. Simply, it tells WordPress to search to see if any functions are attached to it to fire. So do_actions will look something like this:
[php]<?php do_action( 'my-home' ); [/php]

It can also take and pass variables:
[php]<?php do_action( 'my-home' , $var1 , $var2 ); [/php]

The Difference between add_action and add_filter

The difference is primarily and technically semantic. Technically speaking, you can use them interchangeably, but it wouldn't follow code common sense or code "mentality" as one writer said. Filters should filter information, thus receiving information/data, applying the filter and returning information/data, and then used. However, filters are still action hooks.

WordPress defines add_filter as "Hooks a function to a specific filter action," and add_action as "Hooks a function on to a specific action."

add_action

Now, add_actions are a bit different. They hang items on the do_action hook and $priority determines the order.

Say, for example, you have this in your functions.php file:
[php]<?php
add_action( 'hook' , 'bob' );
add_action( 'hook' , 'andy' );
[/php]
The general order is "chronological" meaning if action 'bob' appears (coded/read by the server) before action 'andy', then the action hook 'bob' will fire first. However, with $priority, this order can be interrupted and changed. So...
[php]<?php
add_action( 'hook' , 'bob' , 10 );
add_action( 'hook' , 'andy' , 5 );
[/php]

With add_actions, variables and information may be passed back and forth as needed in the various functions as need. It should also be noted that not all actions are void of arguments or parameters. Some actions do have parameters, so:
[php]<?php add_action( $tag, $function_to_add, $priority, $accepted_args ); ?>[/php]

So, it would look something like this:
[php]<?php add_action( 'hook_name' , 'my_function_name' , 10 , 2 ); ?>[/php]

Extended Version Example
[php]<?php
function echo_comment_id( $comment_ID )
{
echo "I just received $comment_ID";
}
add_action( 'comment_id_not_found', 'echo_comment_id', 10, 1 );[/php]

add_filter

Now WordPress (and my theme) passes much of this page through various filters that check, validate, correct, and even modify various parts. Once it passes through the filter, the information then is applied to an action.

So here is the add_filter function:
[php]<?php add_filter( $tag, $function_to_add, $priority, $accepted_args ); ?>[/php]

This generally looks something like this:
[php]<?php
add_filter( 'filter_name' , 'my_filter_function_name' , 10 , 3 );
function filter_name( $val, $attr, $content = null ) {
//do something
}
?>[/php]

Just like add_actions go with do_actions, the same is true for filters logically speaking. With add_filter you must have apply_filters. Without the filter being called or applied then the filter means nothing, logically.

So, logicaly, in our example with filter 'filter_name', this would modify content/information that is coded like this:
[php]<?php
// Allow plugins/themes to override the default caption template.
$output = apply_filters( 'filter_name', $output , $val, $attr , $content );
if ( $output != '' )
return $output;
[/php]

So, the code is basically saying, “Take the value of the `$output` variable, apply any filters attached to the ‘filter_name’ hook passing the variables $val, $attr, $content to the filter function (whatever that may be and if it accepts them), and assign the filtered value back to the `$output` variable”.

However, technically speaking, PHP is rather forgiving and instead of filtering anything, it can function like add_action, adding the filter to a do_action, not filtering anything, which adds to the confusion. So if you have the following, it will work (though not good form):
[php]</php
do_action( 'my_action' );
add_filter( 'my_action' , 'my_function');
function my_function() {
//do something
}[/php]

Since the add_filter did not have any filters being applied, it worked as an add_action.