What we've learned

Cleaning up your Event code in Craft CMS

Doug St. John

Categorized as: Craft CMS

Event Basics

Craft CMS allows you to do a lot of customization by hooking into Events via a Plugin or Module. You can see the basics of how Events and Hooks work in the documentation.

Here's a full list of Events provided by Craft that you can use in your plugins or modules:

Here's an example Module named `Demo` that runs code after an Element has saved:

            
        

My Plugin/Module is Growing

As a Craft CMS project's size or complexity grows, you'll most likely end up adding a lot of custom business logic to either a Module or Plugin. This may require hooking into more and more of Craft's events. This will inevitably lead to your init() function getting very large and hard to maintain.

Here's an example Plugin named `Demo` that has grown very large (logic removed):

            
        

Solution #1 - Group Event Handlers Into Functions

Group your events in separate functions and call those from init(). This is a simple first step.

            
        

Solution #2 - Put Event Registration in a Separate File

Create an Events.php (or Handlers.php) file in the root of your plugin or module and call that from init().

This cleanly separates your Event setup from the rest of your plugin/module code.

            
        
            
        

Solution #3 - Separate Classes (Recommended)

Create a directory in your plugin/module and create separate PHP classes for each event you're hooking into.

Here are some ideas of how you could structure this:

  • A new /handlers directory at the root (or /listeners if you prefer)
  • Create /events/handlers and keep your events and handlers close

It's up to you since there is currently no Craft CMS recommendation to follow.

We've started converting our plugins and modules to use these invokable classes. It organizes the business logic in descriptively-named classes, it cleans up event/handler registration in our plugins/modules, and you can add private functions as needed. Occasionally, we won't move an event handler to a class if there are only a few lines of logic.

Here are two ways you can set this up via an invokable class or a static function.

            
        

Invokable Class

            
        

Static Function

            
        

Note Regarding Unregistering Events

Yii & Craft can register and unregister events. Something to consider with invokable Event Handler classes is you aren't able to easily unregister a single Event Handler using this method because you don't have a link to the original Event Handler when it's turned on.

Calling the code below will turn off the Event and therefore anything that hooks into it, not just a single Event Handler.

            
        

Summary

If you're working on a simple Craft CMS plugin or module, you may not need to worry about keeping Events organized as you may only have a few. (We'd still suggest Solution #1 or #2 so you'll be ready for the future.) As your plugin or module grows, we'd highly recommend considering Solution #3 so that your Event business logic is separate from Event registration. We'd also recommend using Services to keep your complex logic out of your new classes.

Thanks for reading and I hope this was helpful. You can reach out with questions or feedback at @dstjohn, @flipboxdigital, or the Contact page.