Hooks: WordPress – Actions and Filters

Hooks are what make WordPress plugin development easier for you. There are two types of hooks available on WordPress – Actions and Filters which make WordPress incredibly extensible.

The main difference between actions and filters lies in what they are used for and how they are declared.

Actions allow you to add data or change how WordPress operates. Callback functions for Actions will run at a specific point in the execution of WordPress. Actions do not return anything back to the calling hook. Whereas, filters give you the ability to change data during the execution of WordPress. Callback functions for Filters will accept a variable, modify it, and return it.

You can learn more about them in the Hooks page of the Plugin Developer Handbook.

WordPress Hooks Actions and Filters Introduction

Try it out

One special action that applies to both hooks and filters is the ‘all’ action, which allows a function to be fired for all hooks and filters. See the source for apply_filters() in wp-includes/plugin.php:186-190.

Consider the output of the error console when placing this function in an mu-plugin:

add_action( 'all', function ( $hook ) { error_log( $hook ); } );

Questions for consideration:

For more detail, including the arguments passed to every action and filter, consider the error console output from this function placed in an mu-plugin:

Note: mu-plugins aka Must-Use Plugins are plugins that are installed in a special folder called mu-plugins inside wp-content. These plugins are activated by default and won’t show up in the plugin’s list.

add_action( 'all', function(){ 
	$args = func_get_args();
	foreach ( $args as &$arg ) { 
		if ( is_object( $arg ) ){ $arg = get_class( $arg ); }
		if ( empty( $arg ) ) { $arg = 'false'; }
	$hook = array_shift( $args );
	if ( 
		! in_array( $hook, ['gettext','gettext_with_context'] ) 
		&& false === strpos( $hook, 'option' )
		&& false === strpos( $hook, 'user' )
	) { return; }
	$args = implode(', ', $args );
	error_log( $hook . ( ! empty( $args ) ? ': ' . $args : '' ) ); 
} );

Questions for consideration:

  • The above function uses three lines to skip any hooks not related to options, users, or text translation.
    • How might these lines be changed to focus on other hooks?
    • What’s the difference in filtering approach between strpos() and in_array()?
    • Why is a triple equals sign used when checking the return value of strpos()?
  • What does func_get_args() do?
  • By using the third argument of add_action(), $priority, could you write a timing script to measure processing time for all functions attached to a given hook?
  • If add_action() simply calls add_filter(), what is the difference between an action and a filter? (See do_action() vs. apply_filters() )
    • Answer: A filter always returns a value. Some actions pass a variable by reference — e.g., pre_get_posts passes the active $wp_query object.

Closing thought

What effect would adding this code have on site display?

add_filter( 'render_block', function( $block ){
	return '<img src="https://placekitten.com/' . rand( 200, 400 ) . '" />';