WordPress plugin development tutorial manual - hooks (Hooks)
Hooks are a way to add/modify a piece of code with another piece of code, and are the basis for WordPress plugins and themes to interact with the WordPress kernel, hooks are also widely used in the WordPress kernel.There are two types of hooks in WordPress, Action and Filter.To use hooks, we need to first write a custom function as a When using hooks, we need to write a custom function as the callback function of the hook, and then use the add_action or add_filter function to mount our callback function to the specified Action or Filter.
Action allows us to add some customized actions (such as outputting content to the end of the article) at a certain point in time when the function is executed. Filter is similar to Action, but the difference is that we can modify and return the data through Filter, so the function mounted on Filter will accept some variables and return the modified variables.Simply put, Actions are used to add functionality and Filters are used to modify data.
The WordPress kernel provides many hooks to help developers develop WordPress themes or plugins. By creating custom hooks, we can also allow third party developers to add or modify our features.
WordPress Action and Filter Hooks Reference Links
Action Hooks
Action is one of the two WordPress hooks that provide a capability to run additional functions at characteristic points in time when the WordPress core, theme, or plugin executes.Action and Filter are not the same.
Adding an Action
We can add a function to an Action in two steps; first, we need to create a callback function that will be called when the Action runs. Second, we need to mount this function on the corresponding Action hook. This is accomplished by using the add_action() function, pass at least two arguments $tag (hook name) and $function_to_add (callback function name).
The following example runs when the init hook is executed:
function wporg_custom() {
// Perform certain actions.
}
add_action('init', 'wporg_custom');
We can refer above for a list of available hooks. With increasing development experience, we can find more suitable hooks by looking at the source code of WordPress core, themes or plugins.
Other parameters
add_action() Two additional arguments can also be accepted, $priority (integer) which specifies the priority at which the callback function is executed, and $accepted_args (integer) which specifies the number of arguments passed to the callback function.
prioritization
If a hook has multiple callback functions mounted on it, the hook needs a priority to determine the order in which these callback functions are executed. The priority is an integer with a default value of 10, and the lower the number, the higher the priority. For example, a function with priority 11 will be executed after a function with priority 10, and a function with priority 9 will be executed before a function with priority 10.
For example, the following callback functions are all mounted above the init hook, but they have different priorities.
add_action('init', 'run_me_early', 9);
add_action('init', 'run_me_normal'); // defaults to 10 if no priority is specified
add_action('init', 'run_me_late', 11);
When the above hook is run, the first function to run is run_me_early(), run_me_normal(), and the last function to run is run_me_late().
Number of parameters
Sometimes callback functions need to receive some extra data as an argument to the function. For example, when WordPress saves a post, it will run the save_post
hook that passes two parameters to the callback function: the saved article ID and the article object:
do_action('save_post', $post->ID, $post);
So, when we mount the function to save_post
hook, we can specify that it needs to receive both parameters:
add_action('save_post', 'wporg_custom', 10, 2);
We can then use the parameters provided by the hook in the callback function.
function wporg_custom($post_id, $post){
// Perform certain actions
}
typical example
Let's say we need to modify the query that gets the search results in the WordPress front-end post query, we can use the pre_get_posts
Hook.
function wporg_search($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search) {
$query->set('post_type', ['post', 'movie']);
}
}
add_action('pre_get_posts', 'wporg_search');
Filter Hooks
Filters are the other of the two types of WordPress hooks that allow us to modify the data produced by certain functions through callback functions registered to a particular Filter hook. Unlike Actions, Filters should be run in a standalone fashion and should not have side effects that affect global variables and output.
Add Filter
We can mount a callback function to a Filter in two steps. First, we need to create a callback function that will be called when the Action runs. Second, we need to mount this function on the corresponding Action hook.
We can use the add_filter() function mounts a callback function onto the Filter hook. The add_filter function takes at least two arguments: $tag (character) and $function_to_add (callback function name). The following example will run when the_title Filter is executed.
function wporg_filter_title($title) {
return 'Article:' . $title . 'Modified.' ;
}
add_filter('the_title', 'wporg_filter_title') ;
Assuming we have a post titled "Learning WordPress Plugin Development", the above example will change the title to "Post: Learning WordPress Plugin Development has been modified" when the title is displayed, we can above for a list of available hooks. As we get more experienced, we can find more useful hooks by looking at the source code of the WordPress core, theme or plugin.
Other parameters
add_filter() can also accept two additional arguments, $priority (integer) which specifies the priority at which the callback function will be executed, and $accepted_args (integer) which specifies the number of arguments passed to the callback function. For a detailed description of these parameters, read the section on the Action The chapters.
typical example
exist <body>
Adds a CSS class to the tag when certain conditions are met:
function wporg_css_body_class($classes) {
if (!is_admin()) {
$classes[] = 'wporg-is-awesome';
}
return $classes;
}
add_filter('body_class', 'wporg_css_body_class');
Custom Hooks
A very important but often overlooked practice is in the custom hooks we can use in our plugins so that other developers can extend or modify our plugins. Custom hooks are created and used in the same way as WordPress core hooks.
Create a custom hook
We use do_action() To create Action hooks, use the apply_filters() Create Filter hooks.
Mounting callback functions to custom hooks
We use add_action() to add a callback function to the custom Action hook and add_filter() to add a callback function to the custom Filter hook.
naming convention
Since any theme or plugin can create custom hooks, it is important to add a custom prefix to the hook name to avoid conflicts with the hook name. For example, the Filter named email_body is very prone to product conflict as other plugin developers may choose the same Filter name, which may lead to hard-to-track errors if a user installs both plugins at the same time.
Adding a prefix to the Filter name, such as wporg_email_body (where wporg_ is a unique prefix for our plugin), will avoid Filter name conflicts with other plugins.
typical example
Expandable Action: Setup Form
If our plugin adds a settings form to the "Dashboard", we can use a Custom Action to allow other plugin developers to add their own settings to our plugin.
function wporg_settings_page_html()
{
? >
Foo:
Bar:
<?php
do_action('wporg_after_settings_page_html');
}
Below, another plugin developer mounted a callback function to wporg_after_settings_page_html Action to add the new settings.
function myprefix_add_settings()
{
? >new_settings
New 1:
<?php
}
add_action('wporg_after_settings_page_html', 'myprefix_add_settings');
Expandable Filter: Custom Article Types
In the following example, when we register a custom post type, we pass the post type parameter to a custom Filter, which another plugin developer can modify before creating the custom post type.
function wporg_create_post_type()
{
$post_type_params = [/* ... */];
register_post_type(
'post_type_slug',
apply_filters('wporg_post_type_params', $post_type_params)
).
}
Now, another plugin developer can mount a callback function above the wporg_post_type_params Filter to modify the parameters of the custom post type.
function myprefix_change_post_type_params($post_type_params)
{
$post_type_params['hierarchical'] = true; return $post_type_params; return $post_type_params
return $post_type_params;
}
add_filter('wporg_post_type_params', 'myprefix_change_post_type_params');
External resources
- Michael Fields' Extendable Extensions
- Josh Harrison's WordPress Plugins as Frameworks
- Brandon Dove. The Pluggable Plugin
- Will Norris' WordPress Plugin Pet Peeves #3: Not Being Extensible
Advanced Themes
Remove the callback functions mounted on Action and Filter.
Sometimes we need to remove a callback function that is registered to a hook in a plugin, theme or even WordPress core. In this case, we can use the remove_action() Remove the callback function mounted to Action using the remove_filter() Remove the callback function mounted on the Filter. The parameters passed to remove_action and remove_filter should be the same as those used to register them with the add_action and add_filter functions.
typical example
As an example, we need to remove unnecessary functions to improve the performance of a large theme. Let's take a look at the theme code in function.php
function my_theme_setup_slider()
{
// ...
}
add_action('template_redirect', 'my_theme_setup_slider', 9);
The theme's my_theme_setup_slider function adds a slider module that we don't need, this module loads a very large CSS file and then initializes a JavaScript file that uses 1MB of custom libraries, we can remove this slider module by uninstalling this function.
Since we need to uninstall the my_theme_setup_slider callback function after it has been registered (executed in functions.php), the best time to perform this uninstallation is theafter_setup_theme
Hook.
function wporg_disable_slider(){
// make sure all parameters match the add_action() call exactly
remove_action('template_redirect', 'my_theme_setup_slider', 9); }
}
// make sure we call remove_action() after add_action() has been called
add_action('after_setup_theme', 'wporg_disable_slider'); } // Make sure we call remove_action() after add_action() has been called.
Remove all callbacks
We can use the remove_all_actions() respond in singing remove_all_filters() to remove all callbacks mounted on top of a hook.
Determine the current hook
Sometimes, we need to mount the same callback function on multiple hooks, and in the callback function, we need to determine the corresponding action based on the hook it is mounted to. We can use the current_action() / current_filter() to determine the current Action or Filter.
function wporg_modify_content($content){
switch (current_filter()) {
case 'the_content'.
// do something
break; case 'the_excerpt': // do something
case 'the_excerpt': // do something break; }
// do something
break; }
}
return $content.
}
add_filter('the_content', 'wporg_modify_content');
add_filter('the_excerpt', 'wporg_modify_content'); }
Check if the hook has been run
Some hooks may be called multiple times during execution, but we only want it to be called once, in which case we can use the did_action() to check how many times the hook has run.
function wporg_custom(){
if (did_action('save_post') !== 1) {
return;
}
// ...
}
add_action('save_post', 'wporg_custom');
Debugging with "all" hooks
If we want a callback function to be triggered on every hook, we can mount the callback function on top of the 'all' hook. This is very useful when debugging, to help us determine when an event occurs, when a page crashes, etc.