-
Notifications
You must be signed in to change notification settings - Fork 201
Proposal: A Core Hook System for a More Modular and Extensible JavaScript #322
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
base: dev
Are you sure you want to change the base?
Conversation
Hi @BernhardBaumrock, it's me asking questions again :). You know, I have misunderstood you before in the forums, so I might be wrong again. Let's hope so! But nonetheless, following question: Shouldn't this PR need to also include changes to all the JavaScript in the core for this to be useful? How does your hook system add anything if it's only ever going to be used in code outside of the core? By that, I mean in code you are writing yourself anyway.. code you can just build the modifications in directly without needing hooks. Or just include the single JavaScript class as a library to your codebase. Or let me put it this way: I feel like this only needs to be in the core if the core actually uses it. Because otherwise, you can just let this be a module you can use to add cool functionality to your own code if needed. And also if you add some examples of hookable (and useful!) parts of the JavaScript in the core, it would really help your case because you can build actual examples extending the core's code. |
Hey @poljpocket absolutely valid points. I didn't mention this and it's one of the main reasons for being in the core: If it is not, the core will never use it. And I think it should. If it is in the core, then the core will use it and so can any other JS based module. It's been a tremendously helpful pattern for me in RockCommerce, RockGrid, etc.; You'll only understand once you start adopting to it. And it will never happen if it's a module that you have to install first. I did implement it as a module (RockJavaScriptHooks) first to make sure it works. And it works extremely well! I truly believe this will have a very positive impact on ProcessWire. Think of it that way: What if ProcessWire didn't have the PHP hook system. Would it work? For sure! Would it be possible to customise things? For sure - one way or another. The key takeaway is the following for anybody developing anything based on JS for ProcessWire: Want to make something customisable by the user? Just add three underscores and that's it! Does that answer your questions? |
Oh, and I disagree with your statement that it only adds value if the core uses it! Think about url hooks. They have not been there until they have been added. And when they have been added nothing in the core was using url hooks. Have they been a valuable addition? Absolutely! We could have kept hooking into the 404 process, but url hooks are so much nicer! |
Ok, now I think you misunderstood. What I'm saying is: Shouldn't we modify the JavaScript code in the core to use it and add real-world examples directly in this PR? What does this new addition help if the core JavaScript isn't hookable? I think your examples don't get the point across. It's cool to have a couple of hello-world examples. But that increment in Alpine.js is only useful if the buttons and the first part of the code is actually part of the core and thus something you won't be able to modify without changing the core JavaScript files. But here are examples which come to mind:
I can help if you want. Because I think this is very cool and useful too. |
Hey @poljpocket this sounds great!
Yeah this was left to the imagination of the user and I thought this was obvious :)
That sounds super cool and helpful! If you could add those it would definitely help to show what the PR is about! How should we proceed? I think you could just add another PR that makes those components hookable. This would be a great example of 1) how to add hooks to the core (this PR) and 2) how to refactor existing components to add hooks to them and make them more extendable (your PR) |
I added a draft PR for your PR 😸 |
Hey @ryancramerdesign thx for having a look. I think it's better to discuss my PR here and I guess your comment baumrock#1 (comment) would also belong in this thread. Your comment sounds like you still don't see where this would be useful. Think of a datepicker. At the moment we do customisation via the translation system. It mostly works, but I would consider this a bit hacky as we clearly use the translation system for something different than a translation. Not as long as we talk about locale settings, of course, but what if we wanted to not only translate the datepicker but also modify its behaviour? For example lets say we wanted to add a callback that prevents selecting certain dates. How would we add this to the translation system? Thats just adding three underscores to a method with my PR. Then the user can do anything. Not just things that we thought of upfront but also things we didn't even think of when developing the module. Thats the power of hooks we all know and we all love. Just not in PHP but in JS. |
Hi everyone. Yes, let's continue the discussion here outside of my PR of Bernhard's PR 😄 @ryancramerdesign I think it's important to point out that this proposal has been misunderstood multiple times by me and others: Just to reiterate, to include this in the core, all JavaScript will need to be changed or rewritten because right now, the code isn't designed at all with hooks in mind. Bernhard's proposal isn't at all how the code would look like because it doesn't actually change any code in the core. If he wants to for example make his RookCommerce module hookable, he can do that right now with this implementation. He can do that without changing a line of code in the core. As long as he isn't relying on any fields from the core that is. @BernhardBaumrock That's exactly why I said "your examples don't get the point across" time and time again. We should go ahead and create a real-world example. Your proposal with the date picker is perfect: It's something in the core which right now, can't easily be changed using the current codebase and modules won't be able to do this at all unless the module provides a complete replacement of the datepicker component. I'll get rid of my PR-PR and let's focus on that example and get it done. So, this PR should:
|
Hey @poljpocket thx for the clarification.
I want to clarify as well: All JavaScript in the core CAN stay untouched. This PR will not have any side effects to any existing JS implementations in the core. It will only kick in once a class is "wired" via ProcessWire.wire(...) This means that, to take advantage of hooks, we CAN refactor existing JS (like for the datepicker), but we don't have to. I think it will help a lot once we decide to and until that happens anybody can try out hooks in JS without any risk or without any obligations. Nobody needs to refactor anything - not in the core, not in personal code. @poljpocket if you find time to refactor the core datepicker that would be great. I don't think it's necessary to understand what this PR is about. But maybe I'm wrong. For me it is obvious and I thought it would be obvious for anybody as well that has asked himself this question at least once: "Ok, how do I properly make this configurable by the user?" With hooks the answer is just three underscores away. No messing around with events or callbacks. No additional need for documentation. Only a proven and well known concept that anybody can use and rely on - if he/she wants to. |
It can't because if you look at it, it's not written in any way at all which makes hooks work. Let me make an example: processwire/wire/modules/Inputfield/InputfieldDatetime/InputfieldDatetime.js Lines 104 to 125 in 44fcf13
It is part of the JS code which handles And as I said before, any code NOT in the core doesn't need hookability as a core concept because you the developer can just add hookability to your code by adding something similar to the In that case, this concept then can be offered as a nodejs library or at best a PW module for developers to extend their own JS code with. |
@poljpocket my point is that merging this PR does not mean that we have to refactor hundreds of core JS implementations. We CAN if we want to and if it adds a benefit, but we don't have to. Of course, if we don't change any core implementations than they will not be hookable, that's obvious.
I was just afraid that someone could misinterpret this as that merging my PR means that "all JavaScript will need to be changed/rewritten", which is not the case. I'm proposing a standard that everybody can use so that we all don't have to reinvent the wheel over and over again by adding custom events that somebody can listen to. Or by adding custom translations somewhere that someone can use to modify the behaviour of a module. Or by offering callbacks somewhere that might not even be documented. All we need is three underscores and things will be obvious, coherent, easier to maintain and more powerful. With no overhead and no obligations. |
Hi Ryan,
I'm excited to propose a new feature for the core: a JavaScript hook system that mirrors the power and elegance of our beloved PHP hooks.
This module introduces addHookBefore(), addHookAfter(), and event.replace to any JavaScript object or class. It's designed to make our client-side code as modular, extensible, and fun to work with as the PHP side. Imagine third-party modules being able to cleanly and reliably modify the behavior of core UI components, like modals or page tree actions.
I've included a full set of interactive examples (including an Alpine.js demo) in the ProcessJavaScriptHooks module to showcase how it works.
This could be a huge step forward for ProcessWire's client-side architecture. I'd be thrilled for you to take a look and consider it for the core.
Thanks!
Bernhard
PS: You can either checkout this PR directly or install the standalone module that I have created for development here: https://github.com/baumrock/JavaScriptHooks