Thus if anybody is involved into WordPress development, he/she can not ignore WordPress hooks for a long as it forms the base of WordPress development. Whenever it comes to change existing functionality or create new functionality, one need to turn to the hooks.
Watching the importance of hooks in WordPress development, we are dedicating this post in order to to dispel some of the confusion relating to WordPress. We are describing here start from the basics of WordPress hooks to the creation of hooks. Although the concept of hooks are somewhat daunting for users who are starting out with developing for WordPress, but in reality they are of great use. Here we will find a bit more about just what exactly WordPress hooks are and how they can help you on your way to WordPress rock stardom.
What exactly are WordPress hooks?
As explained above, WordPress hooks are, essentially, triggers of sorts that allow users to, with short snippets of code, modify areas a WordPress theme or plugin, or add their own code to various parts of WordPress without modifying the original files. Hooks are basically divided into two: that is “Action hooks” and “Filter hooks”. The former allows for insertion of custom code at various points while the latter one allows for the manipulation of various bits of content. Lets take a closer look at each of these one by one:
Action Hooks
Action hooks are the designated points in the WordPress core, theme and plugin code where it is possible for outside resources to insert additional code and, thereby, customizing the code to do additional functions. One of the example of this one is “wp_head” action hook; this one is commonly used by many themes and plugins to inject additional CSS stylesheets, processing code or anything else that require to sit between the <head> and </head> tags of their WordPress theme’s XHTML structure. This is the reason why wp_head() is included in all WordPress themes.
Let us create a function in the functions.php file or in the plugin’s code and hook it on using the add_action() function, as follows:
<?php add_action( ‘wp_head’, ‘wpcandy_actionhook_example’ ); function wpcandy_actionhook_example () { echo ‘<meta name=”description” content=”This is the meta description for this page.” />’ . “\n”; } // End wpcandy_actionhook_example() ?>
The above code example adds the text “Hello WPCandy Readers!” between the theme’s <head>tags. Also placing “wp_head” in the call to add_action() with “get_header” would display this text above your theme.
Filter Hooks
Filter hooks are used to manipulate output. It can be used for truncating text, changing formatting of content, or just about any other programming manipulation requirement such as adding to or overriding an array of values.Let us understand this with a precise example; let us add a line or text to the end of the content of each of your blog posts.
Now, custom code can be added as a filter using the add_filter() function. The following code adds a sign-off to the end of each blog post, only when viewing the full blog post screen:
<?php add_filter( ‘the_content’, ‘wpcandy_filterhook_signoff’ ); function wpcandy_filterhook_signoff ( $content ) { if ( is_single() ) { $content .= ‘<div>Th-th-th-th-th That\’s all, folks!</div>’ . “\n”; } // End IF Statement return $content; } // End wpcandy_filterhook_signoff() ?>
The above code adds a new div tag to the end of the content of the blog post, only when on a single blog post screen. A filter hook is just like using the str_replace() function in PHP.
Why Hooks Exist
This is very common question that why hooks exists and there is a need to understand this from the core level. It is very much important to understand the need for them. Let’s create a version of a WordPress function that already exists, and then evolve it a bit using the “hooks mindset.” Watch the following code snippet given below:
function get_excerpt($text, $length = 150)
{
$excerpt = substr($text,$length)
return $excerpt;
}
The above function created takes two parameters: a string and the length at which we want to cut it. Now, here a question can be raised that what will happen if the user wants a 200-character excerpt instead of a 150-character one? Yes, if it does so, no problem will exist there, there is just need to modify the parameter when the users use the function.
Now, it should be noted here that the parameter for the text is usually the post’s content, and that you usually use 200 characters instead of the default 150. So, in this case, wouldn’t it be nice if you could set up new defaults, so that you didn’t have to add the same parameters over and over again? These are the kinds of problems where the WordPress hooks becomes handy to use. Let’s take a quick look at how.
function get_excerpt($text, $length = 150)
{
$length = apply_filters(“excerpt_length”, $length);
$excerpt = substr($text,$length)
return $excerpt;
}
It can be clearly seen in the above code, the default excerpt length is still 150, but some filters has been applied to it. The use of filter here allows to write a function that modifies the value of something, here in this case, the excerpt’s length. Let’s see how it can be used to modify the default value.
function get_excerpt($text, $length = 150)
{
$length = apply_filters(“excerpt_length”);
$excerpt = substr($text,$length)
return $excerpt;
}
function modify_excerpt_length() {
return 200;
}
add_filter(“excerpt_length”, “modify_excerpt_length”);
First of all here, we have defined a function that does nothing but return a number. At this very point, nothing is using the function, so it can be asked to WordPress to hook this into the excerpt_length filter.
Now, later the default excerpt length is successfully changed in WordPress, without touching the original function and without even having to write a custom excerpt function. This is of extreme importance here just because if anyone always want excerpts that are 200 characters long, there is a need to just add this as a filter which let you won’t to specify it every time.
Now, let us suppose, you want to tack on some more text, like “Read on,” to the end of the excerpt. this can be achieved just by modifying the original function to work with a hook and then tie a function to that hook, as shown below:
function get_excerpt($text, $length = 150)
{
$length = apply_filters(“excerpt_length”);
$excerpt = substr ($text,$length)
return apply_filters(“excerpt_content”, $excerpt);
}
function modify_excerpt_content($excerpt)
{
return $excerpt . “Read on…”;
}
add_filter(“excerpt_content”, “modify_excerpt_content”);
This hook is placed at the end of the function which allows to modify its end result. Here, output is also passed to the function that would normally produce as a parameter to the hook and the function that is tied to this hook will receive this parameter.
The Workflow Of Using Hooks
Hooks are frequently used everywhere whether it comes to the coding or publishing of post.
Let us suppose we want to add functionality to the blog that notifies authors when their work is published. To accomplish this there is a need to do something when a post is published. Let us try to accomplish it with the help of hook. So, let’s try to find a hook related to publishing; now again a question raise that whether we need an action or a filter hooks. This depends upon the fact that when a post is published, do we want to modify its data or do a completely separate action. The answer is quite obvious, we need to take an action that time. Thus let us go working with the action filter.
Here we assume hook in the publish_post_hook() function, which hook to schedule pings and enclosures when a post is published.
With some more research in the action list, you’ll find the publish_post hook, and this is what we need. The first thing to do is write the function that sends your email. This function will receive the post’s ID as an argument, so you can use that to pull some information into the email. The second task is to hook this function into the action. Look at the finished code below for the details.
function authorNotification($post_id)
{
global $wpdb;
$post = get_post($post_id);
$author = get_userdata($post->post_author);
$message = “
Hi “.$author->display_name.”,
Your post, “.$post->post_title.” has just been published. Well done!
“;
wp_mail($author->user_email, “Your article is online”, $message);
}
add_action(‘publish_post’, ‘authorNotification’);
Notice that the function we wrote is usable in its own right. It has a very specific function, but it isn’t only usable together with hooks; you could use it in your code any time. In case you’re wondering, wp_mail() is an awesome mailer function — have a look at the WordPress Codex for more information.
This process might seem a bit complicated at first, and, to be totally honest, it does require browsing a bit of documentation and source code at first, but as you become more comfortable with this system, your time spent researching what to use and when to use it will be reduced to nearly nothing.
Priorities
The third parameter when adding your actions and filters is the priority. This basically designates the order in which attached hooks should run. We haven’t covered this so far, but attaching multiple functions to a hook is, of course, possible. If you want an email to be sent to an author when their post is published and to also automatically tweet the post, these would be written in two separate functions, each tied to the same tag (publish_post).
Priorities designate which hooked function should run first. The default value is 10, but this can be changed as needed. Priorities usually don’t make a huge difference, though. Whether the email is sent to the author before the article is tweeted or vice versa won’t make a huge difference.
In rarer cases, assigning a priority could be important. You might want to overwrite the actions of other plugins (be careful, in this case), or you might want to enforce a specific order. I recently had to overwrite functionality when I was asked to optimize a website. The website had three to four plugins, with about nine JavaScript files in total. Instead of disabling these plugins, I made my own plugin that overwrote some of the JavaScript-outputting functionality of those plugins. My plugin then added the minified JavaScript code in one file. This way, if my plugin was deactivated, all of the other plugins would work as expected.
Specifying Arguments
The fourth argument when adding filters and actions specifies how many arguments the hooked function takes. This is usually dictated by the hook itself, and you will need to look at the source to find this information.
As you know from before, your functions are run when they are called by apply_filters() or do_action(). These functions will have the tag as their first argument (i.e. the name of the hook you are plugging into) and then passed arguments as subsequent arguments.
For example, the filter default_excerpt receives two parameters, as seen in includes/post.php.
$post->post_excerpt = apply_filters( ‘default_excerpt’, $post_excerpt, $post );
The arguments are well named — $post_excerpt and $post — so it’s easy to guess that the first is the excerpt text and the second is the post’s object. If you are unsure, it is usually easiest either to look further up in the source or to output them using a test function (make sure you aren’t in a production environment).
function my_filter_test($post_excerpt, $post)
{
echo “<pre>”;
print_r($post_excerpt);
print_r($post);
echo “</pre>”;
}
add_filter(“default_excerpt”, “my_filter_test”);
Variable Hook Names
Remember when we looked at the publish_post action? In fact, this is not used anymore; it was renamed in version 2.3 to{$new_status}_{$post->post_type}. With the advent of custom post types, it was important to make the system flexible enough for them. This new hook now takes an arbitrary status and post type (they must exist for it to work, obviously).
As a result, publish_post is the correct tag to use, but in reality, you will be using {$new_status}_{$post->post_type}. A few of these are around; the naming usually suggests what you will need to name the action.
Who Is Hooked On Who?
It is quite important to understand while in the course of WordPress hook, that actually which function hooks into what. To understand this in better way, the below given script can be used. It is suggested to use this function without arguments to get a massive list of everything, or add a tag to get functions that are hooked to that one tag. Definitely, it will prove as a great one to keep in your debugging tool belt.
function list_hooked_functions($tag=false)
{
global $wp_filter;
if ($tag) {
$hook[$tag]=$wp_filter[$tag];
if (!is_array($hook[$tag]))
{
trigger_error(“Nothing found for ‘$tag’ hook”, E_USER_WARNING);
return;
}
}
else {
$hook=$wp_filter;
ksort($hook);
}
echo ‘<pre>’;
for each($hook as $tag => $priority){
echo “<br /><strong>$tag</strong><br />”;
ksort($priority);
for each($priority as $priority => $function)
{
echo $priority;
for each($function as $name => $properties) echo “\t$name<br />”;
}
}
echo ‘</pre>’;
return;
}
Creating Your Own Hooks
Although there are ton of hooks built into WordPress, but you can also create your own hooks using the above functions you have looked so far. Creating your own hooks will be beneficial especially in the case if you are building a complex plugin intended for wide release as it will make your as well as other developers’ jobs a lot easier.
In the below given code snippet we have created our own hooks assuming that we are here building functionality for users to post short blurbs on the website’s wall. To accomplish that, we will write a function here to check for profanity and hook it to the function that adds the blurbs to the wall. Let us have a look over the full code given as below:
function post_blurb($user_id, $text)
{
$text = apply_filters(“blurb_text”, $text);
if(!empty($text))
{
$wpdb->insert(‘my_wall’, array(“user_id” => $user_id, “date” => date(“Y-m-d H:i:s”), “text” => $text), array(“%d”, %s”, “%s”));
}
}
function profanity_filter($text)
{
$text_elements = explode(” “, $text);
$profanity = array(“badword”, “naughtyword”, “inappropriatelanguage”);
if(array_intersect($profanity, $text_elements))
{
return false;
}
else {
return $text;
}
}
add_filter(“blurb_text”, “profanity_filter”);
The first thing in the code which should be noted is the designation of the function that adds the blurb and the second thing is the apply_filters()function which will be used to add the profanity check. The function array_intersect() will look for array elements that are in both arrays; if there are any, then return false; otherwise, return the original text. The last part actually hooks this function into our blurb-adding script.
Now you must be thinking that how it will be useful to other developers; yes it is; now developers can hook their own functions into this script. They could build a spam filter or a better profanity filter; just they need to do is hook it in.
Mixing And Matching
The beauty of this system is that it uses functions for everything. If you want, you can use the same profanity filter for other purposes, even outside of WordPress, because it is just a simple function. Already have a profanity-filter function? Copy and paste it in; all you’ll need to do is add the one line that actually hooks it in. This makes functions easily reusable in various situations, giving you more flexibility and saving you some time as well.
That’s All
Hopefully, you now fully understand how the hooks system works in WordPress. It contains an important pattern that many of us could use even outside of WordPress.
This is one aspect of WordPress that does take some time getting used to if you’re coming to it without any previous knowledge. The biggest problem is usually that people get lost in all of the filters available or in finding their arguments and so on, but with some patience this can be overcome easily. Just start using them, and you’ll be a master in no time!