Working With WordPress Hooks, How To Create & Use Them.

Chigozie Orunta
5 min readJan 20, 2022

WordPress Hooks are one of the most powerful features in theme and plugin development. They enable WP developers to add custom scripts in a powerful way that most CMS won’t. This makes WordPress truly extensible and versatile for almost any type of web application or project you want to build.

Why Hooks?

Well… A long time ago when WordPress was established as an open-source CMS platform, the inventor (Matt Mullenweg) wanted a way to allow developers to add custom logic or code without needing to tamper with WP core. He & the Automattic team came up with an ingenious way of doing this via Hooks.

These Hooks are classified into 2 types namely: Action & Filter Hooks. The action hooks help you plug in custom code into a WordPress event and do not return any values (they just do stuff), the filter hooks, on the other hand, help you modify the results of a WordPress function, and return the modified values.

Interestingly, Hooks are built into every core aspect of WordPress. There are tons of hooks to give you access to any event or content of the WordPress ecosystem. As they say, if there’s an event or content for it, then there’s most likely a hook for it already within the WordPress API.

For example, when a user saves a post in WordPress it fires an event called the publish_post event. If you wanted to perform more logic after a post is saved, you could do this by simply hooking it to the publish_post hook. The following code checks to see if the post that was saved was a custom post type called Food and then proceeds to send the site owner an email saying a food item has been created:

add_action( 'publish_post' 'notify_if_food', 10, 2 );function notify_if_food( $post_id, $post ) {    if ( 'food' == get_post_type( $post_id ) ) {        $to = 'owner@site.com';
$subject = 'Notification: Food Item Just Created.';
$body = 'A Food Item called ' . $post->post_title . ' was just created.';
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail( $to, $subject, $body, $headers ); }
}

Essentially, there are two parts to a WordPress Hook.

The first part is the WordPress default hook name which is already predefined by the makers of WordPress to help you tie custom logic to specific events or parts of your website. The second part is the callback function that you will create with your custom logic embedded into it to be applied to the default WP hook.

Let’s take a look at the previous example. The first part contains the publish_post event declaration like so:

add_action( 'publish_post' 'notify_if_food', 10, 2 );

This part simply says, use the add_action WordPress command to add a callback function called notify_if_food to the publish_post hook (which fires when a post has just been saved or published by a user). The other parameter, number “10” represents the chronological order in which the custom code should be called (just in case there are other custom codes tied to the same hook) and lastly, the number “2” represents the number of arguments called in your callback function (in this case, $post_id and $post).

The second part represents the callback function:

function notify_if_food( $post_id, $post ) {    if ( 'food' == get_post_type( $post_id ) ) {        $to = 'owner@site.com';
$subject = 'Notification: Food Item Just Created.';
$body = 'A Food Item called ' . $post->post_title . ' was just created.';
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail( $to, $subject, $body, $headers ); }
}

Notice the name of the callback function matches the function string name we passed into the second parameter of the add_action command.

Here are a few examples of favourite hooks of mine and how I apply them:

Log Published Post

add_action( 'publish_post', 'log_published_post' );function log_published_post( $post_id ) {
$log_file = get_stylesheet_directory_uri() . apply_filters( 'log_file', '/log.txt' );
$message = get_the_title( $post_id ) . ' was just saved!';
if ( file_exists( $log_file ) ) {
$file = fopen( $log_file, 'a' );
fwrite( $log_file, $message . "\n" );
}
}

Exclude Categories

add_filter( 'pre_get_posts', 'exclude_categories' );function exclude_categories( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'cat', '-1,-2,-3' );
}
return $query;
}

Independence Day/National Day Notice

add_action( 'admin_notices', 'independence_notice' );function independence_notice() {
global $pagenow;
$admin_pages = [ 'index.php', 'edit.php', 'plugins.php' ];
if ( in_array( $pagenow, $admin_pages ) ) {
if ( date( 'j, F' ) === '1, October' ) {
?>
<div class="notice notice-warning is-dismissible">
<p>Happy Independence Day, Nigeria...</p>
</div>
<?
}
}
}

Comment Notification

add_action( 'comment_post', 'notify_my_mail', 10, 2 );function notify_my_mail( $comment_id, $comment_approved ) {
if ( ! $comment_approved ) {
$comment = get_comment( $comment_id );
$mail = 'you@email.com';
$subject = sprintf( 'New Comment by: %s', $comment->comment_author );
$message = $comment->comment_content;
wp_mail( $mail, $subject, $message );
}
}

Custom WP Login Page Logo

add_action( 'login_head', 'my_logo' );function my_logo() {
echo '
<style type="text/css">
h1 a {
background-image: url('.get_bloginfo('template_directory').'/images/login_logo.png) !important;
}
</style>
';
}

Unauthorized Bot Logs

add_action( 'auth_redirect', 'log_unauthorized_bots' );function log_unauthorized_bots() {
$post = wp_insert_post(
array(
'post_type' => 'logs',
'post_title' => 'Unauthorized Bot Attempt - ' . date("h:i:sa | d, F Y"),
'post_status' => 'publish',
'meta_input' => array(
'ip_address' => $_SERVER['REMOTE_ADDR'],
'attempted_url' => $_SERVER['REQUEST_URI'],
),
)
);
}

WooCommerce Template Custom Styling

add_action( 'wocommerce_before_main_content', 'custom_woo_opening', 5 );function custom_woo_opening() {
if( ! is_product() ) return;
echo '<div class="custom-woo-styling">';
}
add_action( 'wocommerce_after_main_content', 'custom_woo_closing', 50 );function custom_woo_closing() {
if( ! is_product() ) return;
echo '</div>';
}

WooCommerce — Adding Additional Product Item to Cart

add_action( 'woocommerce_add_to_cart', 'add_product_to_cart', 10, 2 );function add_product_to_cart( $item_key, $product_id ) {
global $woocommerce;
$product = wc_get_product( $product_id );
$cart_item = array();
remove_action( 'woocommerce_add_to_cart', __FUNCTION__ );
$woocommerce->cart->add_to_cart( $product_to_add_id, 1, 0, array(), $cart_item );
}

WooCommerce — Empty Cart Notice

add_action( 'woocommerce_check_cart_items', 'empty_cart_notice' );function empty_cart_notice() {
if ( WC()->cart->get_cart_contents_count() == 0 ) {
wc_print_notice( __( 'Your shopping cart is empty! Why?', 'woocommerce' ), 'notice' );
}
}

There you have it, folks… The list is endless as well as the possibilities. Now you can create hooks of your own and extend your WordPress site functionality. Are there hooks of your own you would like to share with us, please let me know in the comments below.

Thanks. Happy Hooking!!!

--

--