Events
PageBlocks hooks standard MODX events. There is no separate event system of its own: one plugin listens to the MODX events the component needs and dispatches them to classes by name.
How dispatch works
The pageblocks plugin is attached to a list of MODX events. On every one of them it builds a class name from the event name and runs it if such a class exists:
OnUserSave → Boshnik\PageBlocks\Events\OnUserSave (framework)
→ PageBlocks\App\Events\OnUserSave (your site)Both run, framework first. That is the whole extension point: to react to an event, drop a class named after it into core/App/Events/. No registration, no plugin editing, no package rebuild.
Writing a handler
<?php
namespace PageBlocks\App\Events;
use Boshnik\PageBlocks\Events\Event;
class OnUserSave extends Event
{
public function run(): void
{
$user = $this->scriptProperties['user'] ?? null;
if (!$user) {
return;
}
// $this->modx - modX
// $this->pb - PageBlocks service
}
}The base class gives you three things:
| Property | What it is |
|---|---|
$this->modx | The modX instance |
$this->pb | The PageBlocks service — assets, paths, script loading |
$this->scriptProperties | Whatever MODX passed to the event |
run() returns nothing. To change behaviour, act on the objects MODX handed you.
Errors are logged, not fatal
A handler that throws is caught by the plugin and written to the MODX log with the event name, class, message, file, line and trace. The page keeps rendering.
That is deliberate — a broken handler should not take the site down — but it also means a handler can fail silently. If something does not happen, read core/cache/logs/error.log before suspecting the dispatch.
The nested-event trap
The plugin reads $modx->event->name once, before the loop:
$eventName = $modx->event->name;$modx->event is a single shared object. If your handler calls $modx->invokeEvent(), the nested call overwrites it — and without the snapshot the next iteration would build a class name from somebody else's event. This has bitten us before; keep it in mind when a handler fires events of its own.
Which events are wired
See Handlers for the list the package subscribes to and what the framework already does on each one.
To listen to a MODX event that is not in that list, add it to the plugin's event list in the manager (System → Events, or the plugin's Events tab) and put your class in core/App/Events/.