Ivan Gretsky Posted August 8, 2020 Share Posted August 8, 2020 Good day! Is there an easy way to add events that some listeners can subscribe to in ProcessWire? I am thinking about adding these events in the template context, so I can add some listeners later. Preferably I'd like to be able to pass some variables to the listener. I am guessing it could be done calling some hookable method of a specially-made class. But please share anything more specific on that if you got some experience, colleagues. Link to comment Share on other sites More sharing options...
kongondo Posted August 9, 2020 Share Posted August 9, 2020 The more I read this the more it sounds like what you are after are custom hooks? Link to comment Share on other sites More sharing options...
teppo Posted August 9, 2020 Share Posted August 9, 2020 A while ago I added an event listener / event queue feature for Wireframe objects: https://github.com/wireframe-framework/Wireframe/blob/master/lib/EventListenerTrait.php. The rough idea is that the object itself keeps track of events and listeners, and if an event is emitted ($this->emit('event-name', $args)), related listeners will be notified. This concept was loosely based on the Vue.js events system. This might be overtly complex for your needs, though. Something as simple as $this->runHooks('event-name', $args) would likely work just fine (though it depends on your use case) ? 3 Link to comment Share on other sites More sharing options...
LostKobrakai Posted August 9, 2020 Share Posted August 9, 2020 Generally I think event handling can quite easily happen outside of processwire with something like https://event.thephpleague.com/2.0/. 2 Link to comment Share on other sites More sharing options...
kongondo Posted August 9, 2020 Share Posted August 9, 2020 Just to add to the discussion....how Laravel does it: https://laravel.com/docs/7.x/events 2 Link to comment Share on other sites More sharing options...
Ivan Gretsky Posted August 9, 2020 Author Share Posted August 9, 2020 26 minutes ago, kongondo said: Just to add to the discussion....how Laravel does it: https://laravel.com/docs/7.x/events This is where I started)) 36 minutes ago, LostKobrakai said: Generally I think event handling can quite easily happen outside of processwire with something like https://event.thephpleague.com/2.0/. Thanks, I'll look into it. But I always try to first use a native solution if it exists) And PW always tried to be all-in-one thing. I am actually thinking about building a module on this feature, so do not want to have an external dependency. 43 minutes ago, teppo said: A while ago I added an event listener / event queue feature for Wireframe objects: https://github.com/wireframe-framework/Wireframe/blob/master/lib/EventListenerTrait.php. The rough idea is that the object itself keeps track of events and listeners, and if an event is emitted ($this->emit('event-name', $args)), related listeners will be notified. This concept was loosely based on the Vue.js events system. This might be overtly complex for your needs, though. Something as simple as $this->runHooks('event-name', $args) would likely work just fine (though it depends on your use case) ? The 1st part I didn't understand) But the second looks promising. Could you share an example of this in a template file context? 1 Link to comment Share on other sites More sharing options...
horst Posted August 9, 2020 Share Posted August 9, 2020 I think in its basic it can be something like https://www.php.net/manual/en/class.splobserver.php ? 3 Link to comment Share on other sites More sharing options...
teppo Posted August 10, 2020 Share Posted August 10, 2020 On 8/9/2020 at 3:37 PM, Ivan Gretsky said: The 1st part I didn't understand) But the second looks promising. Could you share an example of this in a template file context? Do you mean the part about "$this->runHooks('event-name', $args)"? ? If so, what I meant is that you could register your "listener" by hooking into some non-existing method in the TemplateFile object (or class), and then "emit an event" by running hooks: // somewhere early; prepend file or something: $this->addHook('event-name', function(HookEvent $event) { echo "<!-- I'm " . $event->arguments['what'] . " -->"; }); // alternatively you could add the hook in module or init/ready.php: wire()->addHook('TemplateFile::event-name', function(HookEvent $event) { echo "<!-- I'm still " . $event->arguments['what'] . " ->"; }); // then "emit an event" in the template file: $this->runHooks('event-name', ['what' => 'listening']); It's not quite the same thing, there's no queue, syntax is a bit crude... but as I said before, this might be enough, depending on your actual use case ? 4 Link to comment Share on other sites More sharing options...
Robin S Posted August 10, 2020 Share Posted August 10, 2020 @teppo, a bit off-topic but I'm curious about the use of runHooks() because I haven't seen this used before. If you are adding a custom hook method "myEvent", what's the reason to do... $this->runHooks('myEvent', ['what' => 'listening']); ...instead of... $this->myEvent('listening'); 1 Link to comment Share on other sites More sharing options...
teppo Posted August 11, 2020 Share Posted August 11, 2020 @Robin S, that works (in some cases) as well, but there are two reasons why I mentioned runHooks: Direct method call will cause an exception if myEvent hasn't been added as a hook method, runHooks won't. In this sort of scenario (events and listeners) the one emitting the event can't reliably know that someone is indeed listening, so this makes more sense. Direct method calls require that the name be a valid method name, runHooks doesn't. Notice how I used 'event-name' in my example? ? First one is really the key reason, second one is just a little quirk that one might find useful, i.e. it's easier to make sure that your event name can't accidentally clash with a real method. Note: runHooks is tagged with #pw-internal. I've used this before in my code because I really needed it, but it's officially not a part of the public API, and thus in case Ryan decides to alter the implementation at some point, there's a chance that code relying on this feature may need revisiting. Just saying. Using only "official API methods" one would have to either check hooks with getHooks before calling the method (directly or via __call()), or just call it and handle possible exceptions with try ... catch. 5 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now