Hooks and Functions in WordPress

WordPress developments show results very quickly. That is due to the fact that the app is generally fairly well documented and takes the road of least resistance: There is no proprietary template or script language. WordPress is based on a simple PHP and offers plenty of great tools to work with.

Among these tools are the so-called “hooks”. A hook is a marker, and allows the attachment of your own code. That means you are fully in control in terms of which script should be executed. The advantages are clear: No code is executed by mistake or unintentionally. The feature enhances performance and reliability.

There are two types of hooks available in WordPress: Actions and filters. The main difference between the two principles is semantics. Both types of hooks basically do the same thing but in a different context, which is interesting from a programmer’s viewpoint. Actions execute commands. Filters manipulate data and outputs.


Various actions are executed at different locations when WordPress is loaded. For example, we find the following in the /wp-settings.php:


This action (link to source) will be executed once the WordPress basic system has loaded and all plugins have been integrated. This us usually the location where programmers will hook into WordPress with plugins.


This action (link to source) will be executed once the theme files are loaded and all associated data has been processed. Where themes pull in any special features like widgets or menus, then these will usually be executed in this context.

Should a programmer want to attach something to one of these hooks, he can use the function add_action(). This function will register the programmer’s own function at a specific action. Looking at /wp-includes/plugin.php we can see the following:


The function (link to source) add_action() is – as we said above – pretty much the same as a filter, but uses other semantics. Here we have it in black and white. add_action() should, however, be used preferentially, as it also delivers the context. The individual parameters here can be ignored.

The code would look as follows if you attach something to one of these hooks:


Here we hooked the plugin to the action ‘plugins_loaded’. When you now have a look (link to source) at the function do_action(), you will see that all registered actions are being fetched and executed on a loop via the command call_user_func_array(). As soon as WordPress reaches our action, it stops.

WordPress itself has a lot more actions registered at its core. Here now a practical example: Let’s say we want to output another meta tag within the section of the theme. The code for that will look like this:


As you can see here, we can only start from within the action after_setup_theme. That is how we can make sure that all data is loaded. We now register the action that will output the meta tag in the function wpc_my_theme_init().


In WordPress, filters serve the purpose of manipulating existing data. A lot of the variables in WordPress can be filtered. Beginning with small and simple variables, you can go as far as changing the entire content of a blog post.

Filters are registered in WordPress via the command add_filter(). In contrast to actions, the individual parameters (link to source) should not be ignored.


We previously looked at the parameters $tag and $function_to_add in the above example for actions. $tag represents the actual filter, for example the_title, and $function_to_add represents the function to be executed, for example wpc_manipulate_the_title(). The optional parameter $priority indicates the sequence in which to execute the actions. The value 10 is sufficient for most filters. The parameter $accepted_args allows us to specify the number of arguments to be included in a function. This value is of interest, because some filters deliver more than one parameter. More about that in a bit.

Filters are executed in WordPress with the command (link to source) apply_filters(). Just like in do_action(), all registered filters are processed and loaded via call_user_func_array(). If we have a filter in the core, then it could look like this (link to source):


As we can see, there are to registered parameters: $title (this is basically the finished string for a posting title just before it is published) and $id (this is the post ID, which will have that title). Since the command call_user_func_array() is located inside of apply_filters(), all parameters will be delivered with it; interesting here is the fact that only the actual number of parameters as are provided in the parameter $accepted_args. In other words: we can decide if we need all the parameters or maybe only one.

Let’s say you only want to manipulate the title of a post, then the code could look like this:


As you can see here, we are not adding any other parameters for add_filter(), as the default values are perfectly sufficient for our purposes. However, if we do want to load another value to display it at the title, for example from the post meta data, then it would look like this:


Since we are now using both available parameters from apply_filters(), we will have to set the parameter $accepted_args to two. (Since we don’t want to change priorities, we simply set this value to the default value, which is 10.) A parameter array with exactly two values will now be handed over in the function call_user_func_array(). The whole thing can then be extended to for example (link to source) apply up to six parameters in the filter request_filesystem_credentials.

Defining your own Filters and Actions

The approaches provided by WordPress should be followed in your own plugins and themes. I personally find it very helpful to be able to define my own actions and filters. It allows me to expand my own plugin via additional plugins. The plugin WooCommerce is one of the best examples for this approach. It allows the registration of my own actions and filters throughout the source code, which can then be manipulated via plugins. That is why there are several hundred plugins for WooCommerce alone!

As a first example for some of my own actions I would like to show here the template part of a theme (slightly abridged). For context: This template part is accessed from within the single.php via get_template_part().


Two actions are defined here: wpc_my_theme_single_post_before_content and wpc_my_theme_single_post_after_content. Let’s now write a plugin for the theme so that we can use one of these two actions. Of course we could also hook up to the_content. You may come across a use case where these two actions come in handy.


In this example we are dealing with a plugin. Here we have registered an action after all work was complete for the plugin. This offers the option of adding more plugins right after these actions to execute code that would be interesting for this particular plugin.

The procedure is quite similar for filters. It may make sense to register some filters wherever we need to work with defined variables:


Here we have applied a filter with two parameters to the variable $meta. The value can now be influenced via various plugins.

Complex Functions Cleanly Designed

In addition to a neat code style (prefixes, correct naming of functions and variables), a clean design of the more complex functions with multiple parameters is essential. This sample function allows us to asses our options:


A total of three filters are registered in this function: pre_my_plugin_wp_list_categories, my_plugin_wp_list_categories_args, and my_plugin_wp_list_categories. Each one of the filters has a specific purpose:

  • pre_my_plugin_wp_list_categories – This prefilter allows leverage across the whole function to allow defining your own return. The first parameter ‘FALSE’ helps to check for a possible break in the whole rest of the function.
  • my_plugin_wp_list_categories_args – The args filter is meant for functions with more than one parameter. This is where you can manipulate the arguments before the actual program code. The array $args is the forwarding value, which was previously joined with $default_args.
  • my_plugin_wp_list_categories – The return filter allows an additional filtering of the results to add more features as needed. The return filter allows the adding of further meaningful supplement attributes to $return_value and $args.

With these three filters alone you can have one plugin completely changed by another plugin – pluginception, if you like. 😉

Bottom line

Hooks are great tools and should be used to create WordPress expansions. Your own plugins and themes should always come with their own filters. It allows developers to change what we supply without any laborious forking, having to ask for help on the support forum, or any other time-consuming need for contact at all. In effect, you can create things with your own plugin that nobody had thought of at all during the initial development.
This post was originally published on wpcoding.de.

Post Sharing

Author Avatar

Thomas is a WordPress-Developer, who always thinks beyond the tellerrand. Born 1985 and living in Düsseldorf, Thomas loves to play games, enjoys cooking and creating music.

Also Interesting

New Plugin: Slack Connector - Connect WordPress, WooCommerce and Slack

by Michael Firnkes

Initially we merely wanted to optimize our own Slack-processes. With automated notifications from our MarkettPress shop, the blog and our forums. The resul ...

Read more

Inpsyde is the first WordPress.com VIP partner in Germany

by Michael Firnkes

Automattic has given us the title of WordPress.com VIP Service Partner, the first in Germany, Austria and Switzerland. Worldwide, there are only eleven com ...

Read more

Inpsyde is a WooExperts Gold Partner of WooCommerce

by Michael Firnkes

A few weeks ago, Inpsyde GmbH with MarketPress became a certified WooExperts Gold Partner. This is confirmation from WooThemes of our agency’s know-h ...

Read more

BackWPup Pro: Secure WordPress Backup with Google Drive

by Michael Firnkes

The Pro version of our BackWPup plugin supports the backup of WordPress databases and files to Google Drive. But how do you set something like that up? And ...

Read more