One of the things that makes WordPress so powerful is that it makes it easy for you to modify the behavior of a plugin or a theme, or even WordPress itself from another plugin or theme. This allows you to modify the behavior of code that isn’t your own without modifying it. This is thanks to the WordPress “hooks” system that is the backbone of how WordPress plugins work. You can think of hooks, which come in two variations: actions and filters, as places in WordPress where it stops and checks if anyone else wants to do anything before it proceeds.
This is a huge topic and in this article I will cover the basics with some practical examples. Through this you will learn some basics of modifying the behavior of your site as it outputs your content. More importantly, I hope to demystify this very important part of WordPress for you, so that you will be able to understand better how this system works and make sense of the vast number of articles that show you how to use specific hooks.
Actions vs Filters
There are two types of hooks: filters and actions. By convention the most important distinction is that filters return a variable, while actions do not. Actions may expose variables to you that you can use to perform conditional logic tests, but these are not returned.
Think of an action as a place in the code you can “take an action” or “do something.” Actions are like milestones in the execution of your site, where you can run some of your own code. On the other hand, such as outputting inline CSS or JavaScript in the header, using the action “wp_head,” or in the footer using “wp_footer.” When you hook into either of these actions, WordPress will execute the function you hooked to them before continuing.
You should think of filters as an opportunity to modify some piece of data, at a specific point in the execution of your site, before it is used to do something else. For example, every time WordPress outputs a post’s title, it passes through the “the_title” filter. That provides an opportunity for any plugin or theme to hook that filter and change how the title appears.
Where To Put This Code
Before I start explaining in more depth, it’s important to discuss where to put the code we are discussing. The whole point of using actions and filters is so you do not have to modify files that you don’t control directly, so modifying those files makes no sense.
For the kind of code we are talking about in this post you have to options. You can add it to your child theme’s functions.php file or to a custom plugin that you create. Notice that I didn’t say your theme’s functions.php. Again the point is to change the behaviour of another part of WordPress without modifying it directly.
Writing your own plugin may sound intimidating, if you have never done so before, but it shouldn’t. Personally, I like to write several small plugins for each site I work on, each one for a specific goal I need to accomplish. This approach has several advantages over modifying the child theme.
It allows me to disable the plugins individually for testing purposes, it also me to easily reuse them between sites, and most importantly it allows me to test what happens when I switch to another theme. If I had added the code to the child theme, I would lose one of the most important troubleshooting steps: switching to the default theme.
Creating your own plugin is as simple as adding a php file to the plugins directory in your sites content directory (usually called wp-content.) In that file, simply add a valid plugin header, which can be as simple as:
<?php /* Plugin Name: My Plugin */
There is also a plugin for creating other plugins from the WordPress admin. It is called Pluginception and it creates the header for you.
Also, the functions in each of these code examples is prefixed with “slug”. You should change that to the unique slug for the plugin or theme you are working in. This is is important for avoiding conflicts with other plugins or themes as you can only have one function with the same name or you will cause a fatal error.
Using Actions
Another way to think of actions is as a place where one peice of code takes a break and lets other code run. Let’s take a look at a common use of an action in WordPress and then I will break it down for you:
add_action( 'wp_head', 'slug_change_h3_color'' ); function slug_change_h3_color() { if ( is_category( 'news' ) || is_tag( 'important-updates') ) { echo '<style>h3, h3 a { color: red;}</style>'; } }
This will output some inline CSS in header, if the current page is the archive for a particular category or tag. Let’s break down step, by step what is happening in this code.
The first line uses the function add_action()
to hook a function, which follows, to the action. The function, add_action()
has two required parameters, and two optional ones. For now, let’s just look at the required ones.
The first parameter is the name of the action we want to hook this action to. In this example, we are hooking into the action “wp_head”, which is inside of the function wp_head()
that all WordPress themes should have in their header.php file.
That first parameter tells WordPress when to run, the second parameter, the callback, tells WordPress what to run, when it reaches that action. The second parameter is the name of a function to run. You’ll notice that I follow add_action()
, with the actual function that is specified as the callback for add_action()
.
Not everyone works this way, some use add_action() after the callback, some people put them in totally different places. As long as the callback function is somewhere that it can be executed, it works. I do it this way as I think it is the most readable
There are lots of actions in WordPress core, and plugins and themes will add more. I can’t cover them all here. The most common ones that get used for customizing themes are wp_head, which runs in the theme’s header, wp_footer, which runs in the theme’s footer and wp_enqueue_scripts, which is the best way to add additional JavaScript and CSS files to your site. I encourage you to read the codex entries for each and apply the knowledge you gain from this article so that you can see how to put them to use on your site.
Using Filters
Filters are like actions, but they are used to alter some data at a specific place, before it is executed. A very common filter is “the_content” which exposes the content of a post and allows you to alter it before it is outputted in the browser. Most social sharing plugins use this filter to add social sharing buttons before or after post content (such as our own Monarch social sharing plugin).
Another simple use of “the_content” is to add a copyright date to post content. Here is a simple filter and callback
add_filter( 'the_content', 'slug_add_copyright' ); function slug_add_copyright( $content ) { //get current post global $post; //create copyright notice using post date and site name $date = get_the_date( 'y', $post->ID ); $copyright = '<p>Copyright '.$date.' by '.get_bloginfo( 'name' );'.</p>'; //append copyright notice to post content and return $content = $content.$copyright; return $content; }
This is very similar to the code I showed above for actions. The difference here is that the filter provides some data for us to manipulate. In the callback function that data is used as the function’s parameter. In the last line of the callback function we return the variable. If we didn’t return it, there would be no post content.
Get Hooked
In this article I’ve scratched the surface of what WordPress’ hook system allows you to do. This is a huge topic, and the only way to learn is to get your hands dirty and try it. I hope that this article has given you the basics knowledge you need to apply information from the codex, other tutorials and other resources to get the most of this incredibly powerful component of WordPress.
Article thumbnail image by jesadaphorn / shutterstock.com
Thank you Josh Pollock ! Really, it means a lot for the beginners who are trying to find an end to begin. And your article really made me clear about it. Amazing article!
I’m trying to create a customizer control that needs to access Divi $font_choices. In doing this, I’m trying to avoid duplicating all the $font_choices dependancies and related code form Divi.
The control is in my child theme customizer controls.
Any idea how I can accomplish this?
The most helpful article on WordPress Hooks I’ve come across on the web so far! Keep it up.
Very helpful as a starting point for learning plugin/theme development!
(one single quote too many in the 1st line of the 2nd code block though!)
Quick question about filters. If you use a ‘the_content’ filter (like the example), will it be applied to *every* single instance where ‘the_content’ is being used?
Senff-
I’m glad you found this useful. Sorry about that error, I’m not perfect.. unfortunately.
Yes, the_content is applied to every time the_content() runs. But you can use conditional checks inside the filter’s callback, which is quite common. Since you can access the current post’s post object, it’s easy to do. For example:
Take care,
Josh
Josh – This article hooked me! Pun fully intended, but on the serious side, do you have a more in depth guide such as an ebook or blog post series? If not, please consider it.
Mark-
I’m glad you liked the article and found it useful. I don’t have any more articles that I wrote on the subject. I also havn’t written any books on WordPress..yet. I strongly recommend Tom McFarlin’s series on this subject: http://code.tutsplus.com/articles/the-beginners-guide-to-wordpress-actions-and-filters–wp-27373
Take care,
Josh
Thanks for sharing such an article. What you explained is clear to use it. It will help in my blog. Since I am new it will benefit for me. Happy to read such an article.
I use ET for all my sites and they have a lot of shortcodes. Can you use the concepts described here to make changes to shortcode layout or other attributes?
Thanks,
John.
Hooks and Actions actually made WordPress one of most tweakable CMS ever built. You can even change WP core functionality using that techniques.
But wrong usage of them can create WP slow as turtle. That’s why need to use them wisely.
Josh,
This is one of the most enlightening WordPress articles I have read in a long time. I am inspired by your approach in regard to writing plugins instead of modifying the code. This makes so much sense since you can reuse the plugins and disable them as needed, two points you mentioned. I may even try to write my own after reading this. Thanks, and have a great day 🙂
Adam
Adam-
I’m glad you liked this article and I’m glad it inspired you. I was once too intimidated to write plugins. Now I write several a day. I really encourage you to create a local test site and experiment with these concepts. The internet is full of helpful resources on how the plugins API that powers this works.
Take care,
Josh
How many plugins have you written today?
Three, across two client sites. Now if only they all worked:)
I just throw code into the Code Snippets plugin – that’s kinda like writing my own plugin, right? lol