-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removing hooks #2701
Comments
Lesson Development Checklist
|
2 similar comments
Lesson Development Checklist
|
Lesson Development Checklist
|
@CrochetFeve0251 Let me know if you would like to continue with drafting a script for this next lesson in the module. |
ScriptIntroductionSometimes when doing some compatibility with another plugin, some logic added by another plugin or a theme is creating an incompatibility. Removing a callback from a hookTo remove a callback, we have two functions based on the hook type. FilterIn the case of a filter, we can use the function To understand further how this works, let's take an example. Imagine I got the function function my_callback() {
}
add_filter('my_filter', 'my_callback', 12); To remove that callback, I will have to call the function remove_filter('my_filter', 'my_callback', 12); ActionIn the case of an action, we can use the function To understand further how this works, let's take an example. Imagine I got the function function my_callback() {
}
add_filter('my_action', 'my_callback', 12); To remove that callback, I will have to call the function remove_action('my_action', 'my_callback', 12); Removing all callbacks for a hookFirst, I need to warn you doing this is not recommended because it can remove important hooks for certain plugins or themes, and it is more recommendable to remove only the callback which creates an incompatibility. If you want to remove all callbacks from an action, you can use the method remove_all_actions('my_action'); For a filter you can use remove_all_filters('my_filter'); It is also important to note that these methods should not be called from inside the hook you want to remove otherwise this would result in an infinite loop. |
@jonathanbossenger I didn't add much more than what is in the documentation as I don't see much more information that would be useful for that section which is not in the documentation. |
Sometimes those are the easiest lessons to script 😁 I will review this week. |
Edited Script Removing HooksIntroductionWhile the WordPress hooks system makes WordPress very extendable, it can sometimes create incompatibilities with your plugin’s execution. In this lesson you will learn about removing hook callback functions. ExampleLet’s say you are developing a plugin that will add some a copyright text string with a date to the end of every page on a WordPress site. Your plugin code might look something like this: <?php
/**
* Plugin Name: Add Copyright
* Description: Add Copyright with current year to all Pages
* Version: 1.0
* Author: Jon Doe
*/
namespace JonDoe\AddCopyright;
add_filter( 'the_content', __NAMESPACE__ . '\add_copyright' );
function add_copyright( $content ) {
if ( ! is_page() ) {
return $content;
}
$year = date( 'Y' );
return $content . "<p>© $year</p>";
} You receive a support request from a user who is using your plugin, complaining that there is some other text being added to the end of the page content that is not related to your plugin. You investigate and find that another plugin is adding some text to the end of the page content based on an Extra Option setting. You realize that the other plugin is adding the extra text to the end of the page content using the same filter hook as your plugin. <?php
/*
Plugin Name: WP Learn Extra Content
Version: 1.0.0
*/
namespace WP_Learn\Extra_Content;
add_action('admin_init', __NAMESPACE__ . '\add_option');
function add_option() {
add_settings_field('wp_learn_extra_option', 'Extra Option', __NAMESPACE__ . '\extra_option_field', 'general');
register_setting('general', 'wp_learn_extra_option');
}
function extra_option_field() {
echo '<input name="wp_learn_extra_option" id="wp_learn_extra_option" type="text" value="' . get_option('wp_learn_extra_option') . '" />';
}
add_filter( 'the_content', __NAMESPACE__ . '\add_extra_option' );
function add_extra_option( $content ) {
$extra_option = get_option('wp_learn_extra_option');
if ( ! $extra_option ) {
new \WP_Error( 'wp_learn_extra_option', 'Extra content is empty.' );
return $content;
}
$content .= '<p>' . $extra_option . '</p>';
return $content;
} The plugin user wants only the copyright text to be displayed on pages, but to retain the other plugin’s functionality on all other post types. In that situation there is little you can do except to somehow remove the incompatible callback function hooked into the same filter. Removing a callback from a hookFortunately, WordPress allows you to remove a hooked callback, depending on the hook type. FilterIn the case of a filter, you can use the In order to remove a callback hooked into a filter, we call the function, passing the filter name and the callback function name to remove. remove_filter( 'the_content', 'WP_Learn\Extra_Content\add_extra_option' ); If the callback function was added with a priority, you can also pass the priority as the third argument. remove_filter( 'the_content', 'WP_Learn\Extra_Content\add_extra_option', 10 ); In this specific case, the copyright text should only be displayed on pages, so you should only remove the other plugin’s callback function when the content being rendered is actually page. if ( ! is_page() ) {
return;
}
remove_filter( 'the_content', 'WP_Learn\Extra_Content\add_extra_option' ); Ideally, you should also remove any callbacks at the right point in request execution. In this specific case, a good place to remove the callback would be at the add_action( 'wp', 'custom_remove_extra_option_hook' );
function custom_remove_extra_option_hook() {
if ( ! is_page() ) {
return;
}
remove_filter( 'the_content', 'WP_Learn\Extra_Content\add_extra_option' );
} This code could be added to a custom plugin, or a child theme’s ActionIn the case of an action, you can use the As with removing a filter, you call the function, passing the action name and the callback function name to remove. remove_action( 'admin_init', 'hooked_callback_function' ); Again, if the callback function was added with a priority, you can also pass the priority as the third argument. remove_action( 'admin_init', 'hooked_callback_function', 10 ); Removing all callbacks for a hookIt is also possible to remove all callbacks for a specific hook. Doing this is not generally recommended as it can remove important hooks for certain plugins or themes, and it is better to remove only specific hook callbacks which create incompatibilities. If you do want to remove all callbacks from an action, you can use the To remove all callbacks from a filter you can use the For both functions you pass the hook name as the first argument, and optionally the hook priority as the second. It is also important to note that these functions should not be called from inside the hook you want to remove the callbacks from, otherwise this would result in an infinite loop. |
@CrochetFeve0251 thanks for your first draft. I've edited the script to include an example of the type of conflict the script is talking about, using the example plugin from the lesson on Naming Collisions. I've also added links to the various function references. Let me know if you're happy with the edited version or if you have any further edits/suggestions. Once you're happy with it, we can pass it on to a video creator. |
@jonathanbossenger inside the example code I see that: if ( ! $extra_option ) {
new \WP_Error( 'wp_learn_extra_option', 'Extra content is empty.' );
return $content;
} I am wondering if you were meaning that? if ( ! $extra_option ) {
return new \WP_Error( 'wp_learn_extra_option', 'Extra content is empty.' );
} For that example: add_action( 'wp', 'custom_remove_extra_option_hook' );
function custom_remove_extra_option_hook() {
if ( is_page() ) {
remove_filter( 'the_content', 'WP_Learn\Extra_Content\add_extra_option' );
}
} Maybe we would like to show them logic where they bail out early on rather than putting the main logic inside the condition: add_action( 'wp', 'custom_remove_extra_option_hook' );
function custom_remove_extra_option_hook() {
if ( ! is_page() ) {
return;
}
remove_filter( 'the_content', 'WP_Learn\Extra_Content\add_extra_option' );
} Last but not least I don't see anymore the example for removing all hooks, did you remove it or you forgot to add it back? |
No, I had intended the code that is there so that it throws the error gracefully, but the code execution still continues, as you need to return the $content variable for the
Yup, I agree, I updated the code example.
I actually left that out on purpose, in the video we can show the link to the documentation, but since it's generally recommended anyway, I didn't think that adding examples of how to use it were of any benefit to the lesson. But I'm happy to include a note about it for "FYI" purposes |
@CrochetFeve0251 replied to your feedback (thanks) let me know if you have any other feedback on my replies. |
Hello! I was just reviewing the conversation here and think an important concept is missing for the advanced plugin developer: preventing infinite loops. This is actually most often the reason I want to remove a hook, and I've often seen it done in plugins like WooCommerce, for instance, where a hook will be removed, some logic will be performed, and then the hook will be immediately added back. Is this a code pattern worth discussing in this lesson? |
Details
Prerequisites
It is assumed that the learner has already completed the following lessons:
Learning Objectives
Related Resources and Other Notes
Automation Code
//lesson
The text was updated successfully, but these errors were encountered: