Every CRUD-style entity (article, category, media, user, preference, role, webset) fires the same family of events. The hook name is <entity>.<event>.
Generic write events
| Hook | Type | When |
<entity>.beforeSave | filter | Before any write — mutate the data |
<entity>.afterSave | action | After any write |
<entity>.beforeInsert | action | Before INSERT only |
<entity>.afterInsert | action | After INSERT only |
<entity>.beforeUpdate | action | Before UPDATE only |
<entity>.afterUpdate | action | After UPDATE only |
<entity>.beforeDelete | action | Before DELETE |
<entity>.afterDelete | action | After DELETE |
Specials
| Hook | Type | Purpose |
media.afterUpload | action | Fires after a file lands in /media/uploads/ |
user.afterLogin | action | After a successful password verify |
admin.menu | filter | Add items to the admin sidebar |
admin.dashboardCards | filter | Add cards to the dashboard |
admin.healthChecks | filter | Register entries for the health page |
editor.toolbarButtons | filter | Add buttons to the article editor |
Examples
// Auto-lowercase article slugs before save
add_filter('article.beforeSave', function ($data) {
$data['slug'] = strtolower($data['slug'] ?? '');
return $data;
});
// Post to a webhook on publish
add_action('article.afterUpdate', function ($article, $id) {
if ($article['status'] !== 'published') return;
@file_get_contents('https://hooks.example.com/published?id=' . $id);
});
// Add a "Reports" item to the sidebar
add_filter('admin.menu', function ($items) {
$items[] = [
'label' => 'Reports',
'href' => './plugins/reports/page.php',
'icon' => 'ic:round-bar-chart',
'min_level' => 2,
];
return $items;
});