-
Notifications
You must be signed in to change notification settings - Fork 103
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
Custom hooks #2700
Comments
Lesson Development Checklist
|
@jonathanbossenger As you requested, I moved the comment to the right issue. Should we talk about the fact filters are not returning a guaranteed type? (I didn't see it mentioned anywhere in the documentation) I think that could help them adopt good practices from the standard and not spend hours trying to figure out what is the problem in their code when it comes from a wrong callback on the website from a client. I also did some page about that topic here which explains the issue and how we are currently solving this at WP Media. Maybe it could inspire us for this tutorial. |
Thanks. So this objective for this lesson will be focused on creating your own custom hooks in a plugin, either filter or action. I agree that it's useful to know what data types are returned by filters. I've never experienced this but I'm guessing that this probably happens due to developers not returning the same type of data as the filter callback receives. To the best of my knowledge, WordPress core doesn't return different types when it hooks into filters. It probably doesn't completely fit the objective for this lesson, though, unless we consider including a section on the fact that it's not really possible to "force" a specific data type to be returned from a filter callback. However, what might work is if we added a new lesson to the Advanced Hooks module, which included what you've described here, and other things like Determining the Current Hook and Checking How Many Times a Hook Has Run. These are smaller pieces of knowledge that are useful to the learner but don't quite have enough content to warrant an entire lesson on the subject. What do you think? |
Yes, the base issue comes from the callback returning the wrong value. However, what we noticed at WP Media is that when that happens as the error message says it comes from the inside of the plugin, then clients tend to contact us to fix the issue. (We use extensively custom hooks in WP Rocket to keep the plugin standard while allowing users to modify its behavior to their needs) I don't think the issue should be present in the core at there are reviews that prevent that kind of errors. However, it will be present for sure if a developer creates a plugin with custom hooks and uploads it on the WordPress repository as plugin users aren't always that experienced with WordPress code. Then it could be part of a whole part by itself, or it can just also be a simple remark to make during the class when talking about the difference between actions and filters. All depends on the importance you give to that point. PS: We do a bit of the same thing when working with data sent through forms by the users. |
Got it, I understand. So, the goal for this lesson is to focus on developers creating their own custom hooks for others to extend, but this issue could also occur as you say, if developers even use core hooks incorrectly. Therefore, I'm not sure a note about filter return values makes sense in this lesson, but I do think creating a new lesson described above does. I've created a new issue here, and we can add this to that lesson. |
I put my draft here, so it will be visible to everyone while I work on it. ScriptAll websites have their own unique requirements. As you might expect with your plugin, it is just impossible to be able to satisfy all of them at once with a closed code base they cannot modify cleanly. That way your plugin will often end up being really close to fixing someone else's issue but always with one of two details that are missing to make it a perfect solution for them. But what if I was telling you there was a way to not be the bad guy here and prevent users using your plugin from having to face that issue? In that lesson we will be focusing on custom hooks: the perfect way to make your users able to make your plugin feat their needs perfectly. Custom hooksCustom hooks are just like regular hooks that you are using in WordPress and which are defined by the core. However, this time you are behind the wheel. Why use custom hooks?Custom hooks are a great way to keep focus on your plugin main logic and avoid being slowed down by third-parties compatibilities as users have now a way to handle that kind of scenarios themselves and will report you their solution when they find one. Another advantage of custom hooks is that it is possible for your user to customize your plugin behavior to their needs and link it to their own features. Creating of a custom actionCustom actions are often created in one scenario: You want to warn something is going to happen or already happened. For that it is possible to call the function do_action('my_action'); When necessary, it is then also possible to pass a context to the action the callbacks will be able to use adding more parameters to the function: $count = 10;
$is_admin = true;
do_action('my_action', $count, $is_admin); Once this is done, then context parameters will be available to be used by the callback functions on the action: function my_callback(($count, $is_admin) {
// custom logic
}
add_action('my_action', 'my_callback', 10 , 2); Creation of a custom filterFilters are a way to change a value that you rely on for your users. As a custom hook, it is a great way to offer a choice for experts while making a decision for more novice users, preventing them from being confused with notions they don't master. To create a custom filter, you need to use the function apply_filters('my_filter', false); It is also possible to pass a context to callbacks adding more parameters: $count = 10;
$is_admin = true;
apply_filters('my_filter', false, $count, $is_admin); Once this is done, then context parameters are available this way on callbacks: function my_callback(($value, $count, $is_admin) {
// custom logic
}
add_filter('my_filter', 'my_callback', 10 , 3); Conflicting nameWordPress has its own specificities when it comes to naming filters and actions. If you don't want to end up with some weird filter or action behaviors, then you might be interested in using these rules. Conflict between pluginsA WordPress plugin is like a flat. By that I mean that you are not alone as there are other plugins and themes in the same WordPress instance. This is why it is really important to understand that everyone shares the main namespace and thus you should not pollute it. When it comes to custom hooks, you can respect that rule by always prefixing your hook names with the slug from your plugin: do_action('my_plugin_my_action'); That way if someone else has created another with the same name, then it won't be conflicting with yours as each one will be inside their own namespace. Conflicts between filters and actionsBehind the hoods, actions and filters are the same thing as for WordPress actions are just filters returning nothing. This is why it is important to mind that naming a filter the same as an action will result in conflicts with callback registered to the action or filter being for the action and the filter. For that reason you should always use unique names for each hook and not make the name being unique only to actions or filters. |
Let me know when you feel like you're finished with your first draft, and I'll review. |
@jonathanbossenger while looking on the documentation there is a part about hook name conflicts, do you think that part should be here or in good practices? https://developer.wordpress.org/plugins/hooks/custom-hooks/#naming-conflicts |
@CrochetFeve0251 good question. I think adding it to this lesson makes a lot of sense. |
@jonathanbossenger I think I am good for that script feel free to review it. |
Nice work. I have two general points of feedback from my first review.
There are some other grammar-related items, but I think a good first step is to update the script based on these changes, and then I can do a grammar review. |
Hi @CrochetFeve0251 I just wanted to check if the script is ready for a second review? |
@webcreativeng we are getting close to having a script ready to create a video from, I wanted to check if you are still available to create videos for this module? |
@jonathanbossenger Sorry I forgot about the intro. What do you think about the new intro? |
Edited script IntroductionAs a plugin developer, you’ll probably try to cover all possible use cases when building your plugin’s functionality. However, all websites have unique requirements, and it’s impossible to satisfy all of them. This sometimes means your plugin will end up being really close to what a potential user needs but might need one or two minor additions that would make it a perfect solution. Fortunately, there was a way to allow your plugin’s users to extend its functionality without editing the plugin code. In that lesson, you will learn about custom hooks, the perfect way to enable your users to customize your plugin to their needs. Custom hooksCustom hooks are just like regular hooks you’ve already learned about, which are defined by WordPress Core. However, this time, you are behind the wheel. You can create either custom action hooks or custom filter hooks through your plugin code, to enable other users or developers the ability to extend the functionality of your plugin. Why use custom hooks?Custom hooks are a great way to keep focus on your plugin’s main functionality. They make it possible for your plugin user to customize your plugin behavior to meet their needs and implement their own features. They also allow you to avoid having to worry about making your plugin compatible every single possible external integration. As custom hooks give users a way to implement their own custom scenarios themselves they will often report their solution back to you when they find one, which you can share with the rest of your users. Creating a custom actionYou would often create custom actions to trigger before something specific is going to happen or after something specific has happened. To do this, you call the do_action('my_action'); It is also possible to pass a context to the action. do_action('my_action', ‘context’); The context parameters will then be available to be used by any callback functions hooked on the action: $count = 10;
$is_admin = true;
do_action( 'my_action', $count, $is_admin ); add_action( 'my_action', 'my_callback', 10 , 2 );
function my_callback( $count, $is_admin ) {
// custom logic
} Creating a custom filterCustom filters are a way to allow someone to change the value of something you define in your code. It allows you to make a specific decision for how your code functions for plugin users, but also allow more experienced users the ability to extend that decision to suit their requirements. To create a custom filter, you call the $enabled = false
apply_filters('my_filter', $enabled); With this in place, someone could hook into the filter, and set the value to true, if this was their requirement. Like custom actions, it is also possible to pass a context parameter: $count = 10;
$is_admin = true;
apply_filters('my_filter', false, $count, $is_admin); Once this is done, then context parameters are available on callback functions hooked into the filter: add_filter( 'my_filter', 'my_callback', 10 , 3 );
function my_callback( $value, $count, $is_admin ) {
// custom logic
} Naming conflictsIn the lesson on Naming Collisions, you learned how to avoid naming conflicts in the global namespace. This is also true when creating custom hooks. Conflict between pluginsWhen creating custom hooks, you should always prefix your hook names with a unique identifier, ideally the same one used elsewhere in your plugin: do_action('my_plugin_my_action'); That way, if someone else creates another hook with a similar name, it won't conflict with yours, as each one will be prefixed with its own unique identifier. Conflicts between filters and actionsUnder the hood, actions and filters are functionally the same, the main difference being that actions don’t return a value and filters do. For that reason, you should always use unique names for each hook. Don’t create an action and a filter with the same name. // This is wrong
do_action('my_hook');
apply_filters('my_hook', $some_variable) Doing this will result in conflicts with callback functions registered to the action or filter, as it means the callback will run both when the action and filter are triggered. Depending on whether you hook a callback into the action or filter, it may also cause errors in the code execution. |
@CrochetFeve0251, thanks for the updated intro. I have edited your script, mostly to improve its clarity, tweak some of the code examples, and refer to the Naming collisions lesson, which was recently added to the first module. 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 onto @webcreativeng to start creating the video, and get started on the next lesson script. |
@jonathanbossenger it seems good to me |
@webcreativeng this video is ready to be created. Are you able to give us an estimated time for a first draft? |
Great. I guess I can get started. I've looked at some existing videos for context for my video, but I'm just wondering if there is documentation on 'video creating' for proper guidance. As per the timeline, I guess I can work to have a draft before WCUS, if that's okay. Thank you |
@webcreativeng thanks.
We do have some guidelines, but they are not very prescriptive. There are some tips on creating the video portion of a lesson in the Creating a Lesson page There is also the Video best practices, which contains a lot of useful information. For these types of technical videos, I recommend reading the section on Guidelines for creating technical videos that include code examples. One thing you could try is to maybe just focus on a smaller section of the script as a first draft, and then share it here for feedback. That way you get a feel for the process, and you can get feedback on the video output. |
@webcreativeng I am just doing some check-ins, and I wanted to make sure you still feel comfortable getting your first draft ready before WCUS, which is next Tuesday, 17 September. Let me know if there's anything I can do to support you. Thanks |
Thanks @jonathanbossenger Regards, |
Yup, that's completely fine. If possible, could I ask you to either document those changes here or (even better) submit them as a pull request on the original script in this repository, as the script will be used for the lesson content when the lesson is added to Learn.WordPress.org. |
Ok, here is the first part of the video, draft, for feedback before I complete the rest. Thank you. |
@webcreativeng thank you, I will review it this week. |
It looks great, @webcreativeng; I especially like the graphic you used for the "close but not quite" scenario. No immediate feedback at this time, please feel free to go ahead and complete the rest of the video. EDIT: it would be helpful if you're able to share a found idea of what you'll have the final video ready for review. |
@webcreativeng I'm checking in to see how this video progresses. I would also like to mention that if things have gotten busy for you and you can't contribute now, that's also OK. Just let us know. Thanks |
Video for review: https://drive.google.com/file/d/1ITUiBfd3stRbUZuFIn9eEjsKOXvth44f/view?usp=drive_link Note to reviewers, at about 4:41 there is a screenhost of a GitHub issue for a lesson. This lesson hasn't been published yet, as soon as it is I will add it to the video. |
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: