Developers

Events

Navigation provides a collection of events for extending its functionality. Modules and plugins can register event listeners, typically in their init() methods, to modify Navigation’s behaviour.

Menu events provide a Menu Settings object through $event->menu. They concern menu configuration, rather than individual node edits or menu field values. MenuEvent does not support cancellation through isValid.

The beforeSaveMenu Event

The event that is triggered before menu configuration is validated and saved.

use verbb\navigation\events\MenuEvent;
use verbb\navigation\services\Menus;
use yii\base\Event;

Event::on(Menus::class, Menus::EVENT_BEFORE_SAVE_MENU, function(MenuEvent $event) {
    $menu = $event->menu;
    $isNew = $event->isNew;
    \Craft::info(($isNew ? 'Creating' : 'Updating') . " menu {$menu->handle}.", __METHOD__);
});

The afterSaveMenu Event

The event that is triggered after menu configuration has been saved.

use verbb\navigation\events\MenuEvent;
use verbb\navigation\services\Menus;
use yii\base\Event;

Event::on(Menus::class, Menus::EVENT_AFTER_SAVE_MENU, function(MenuEvent $event) {
    $menu = $event->menu;
    $isNew = $event->isNew;
    \Craft::info(($isNew ? 'Creating' : 'Updating') . " menu {$menu->handle}.", __METHOD__);
});

The beforeDeleteMenu Event

The event that is triggered before a menu deletion is requested.

use verbb\navigation\events\MenuEvent;
use verbb\navigation\services\Menus;
use yii\base\Event;

Event::on(Menus::class, Menus::EVENT_BEFORE_DELETE_MENU, function(MenuEvent $event) {
    $menu = $event->menu;
    \Craft::info("Deleting menu {$menu->handle}.", __METHOD__);
});

The beforeApplyMenuDelete Event

The event that is triggered before a menu deletion is applied from project config.

use verbb\navigation\events\MenuEvent;
use verbb\navigation\services\Menus;
use yii\base\Event;

Event::on(Menus::class, Menus::EVENT_BEFORE_APPLY_MENU_DELETE, function(MenuEvent $event) {
    $menu = $event->menu;
    \Craft::info("Applying deletion of menu {$menu->handle}.", __METHOD__);
});

The afterDeleteMenu Event

The event that is triggered after a menu has been deleted.

use verbb\navigation\events\MenuEvent;
use verbb\navigation\services\Menus;
use yii\base\Event;

Event::on(Menus::class, Menus::EVENT_AFTER_DELETE_MENU, function(MenuEvent $event) {
    $menu = $event->menu;
    \Craft::info("Deleted menu {$menu->handle}.", __METHOD__);
});

Node Events

The beforeSave Event

The event that is triggered before a node is saved. Read the node from $event->sender; set $event->isValid to false to prevent the save.

use craft\events\ModelEvent;
use verbb\navigation\elements\Node;
use yii\base\Event;

Event::on(Node::class, Node::EVENT_BEFORE_SAVE, function(ModelEvent $event) {
    $node = $event->sender;
    \Craft::info("Saving node {$node->title}.", __METHOD__);
});

The afterSave Event

The event that is triggered after a node is saved.

use craft\events\ModelEvent;
use verbb\navigation\elements\Node;
use yii\base\Event;

Event::on(Node::class, Node::EVENT_AFTER_SAVE, function(ModelEvent $event) {
    $node = $event->sender;
    \Craft::info("Saved node {$node->title}.", __METHOD__);
});

The modifyNodeActive Event

The event that is triggered when a node’s active state is calculated. Set $event->isActive to override branch highlighting; this does not change the exact current-page match. This example highlights a node named Campaign.

use verbb\navigation\elements\Node;
use verbb\navigation\events\NodeActiveEvent;
use yii\base\Event;

Event::on(Node::class, Node::EVENT_NODE_ACTIVE, function(NodeActiveEvent $event) {
    if ($event->node->title === 'Campaign') {
        $event->isActive = true;
    }
});

Structure Events

The beforeUpdateElement Event

The event that is triggered before an existing element is moved within a structure. These Craft events apply to other element types too, so check that $event->element is a Navigation node.

use craft\events\MoveElementEvent;
use craft\services\Structures;
use verbb\navigation\elements\Node;
use yii\base\Event;

Event::on(Structures::class, Structures::EVENT_BEFORE_UPDATE_ELEMENT, function(MoveElementEvent $event) {
    if ($event->element instanceof Node) {
        \Craft::info("Moving node {$event->element->title}.", __METHOD__);
    }
});

The afterUpdateElement Event

The event that is triggered after an existing element is moved within a structure. These Craft events apply to other element types too, so check that $event->element is a Navigation node.

use craft\events\MoveElementEvent;
use craft\services\Structures;
use verbb\navigation\elements\Node;
use yii\base\Event;

Event::on(Structures::class, Structures::EVENT_AFTER_UPDATE_ELEMENT, function(MoveElementEvent $event) {
    if ($event->element instanceof Node) {
        \Craft::info("Moving node {$event->element->title}.", __METHOD__);
    }
});

Node Type Events

The registerNodeTypes Event

The event that is triggered when Navigation registers its node types. Add classes to $event->types. This example registers the Group class from Node Types.

use modules\sitemodule\nodetypes\Group;
use verbb\navigation\events\RegisterNodeTypeEvent;
use verbb\navigation\services\NodeTypes;
use yii\base\Event;

Event::on(NodeTypes::class, NodeTypes::EVENT_REGISTER_NODE_TYPES, function(RegisterNodeTypeEvent $event) {
    $event->types[] = Group::class;
});

Dynamic Source Events

The registerDynamicSources Event

The event that is triggered when Navigation registers its Dynamic source providers. Modify $event->providers to add or remove provider classes. This example removes asset volumes from the available Dynamic sources.

use verbb\navigation\dynamic\sources\AssetVolumeDynamicSource;
use verbb\navigation\events\RegisterDynamicSourceEvent;
use verbb\navigation\services\DynamicSources;
use yii\base\Event;

Event::on(DynamicSources::class, DynamicSources::EVENT_REGISTER_DYNAMIC_SOURCES, function(RegisterDynamicSourceEvent $event) {
    $event->providers = array_values(array_filter(
        $event->providers,
        fn($provider) => $provider !== AssetVolumeDynamicSource::class,
    ));
});

Custom providers must implement verbb\navigation\base\DynamicSourceProvider, or extend DynamicSource. See Dynamic Sources for the extension contract.

Cache Events

The invalidateNavigationCache Event

The event that is triggered when Navigation invalidates its cache. The payload provides tags, plus nullable menuUid, siteId, and nodeId properties. Source-wide invalidations may have tags without menu, site, or node identifiers.

use verbb\navigation\events\NavigationCacheInvalidationEvent;
use verbb\navigation\services\NavigationCache;
use yii\base\Event;

Event::on(NavigationCache::class, NavigationCache::EVENT_INVALIDATE, function(NavigationCacheInvalidationEvent $event) {
    \Craft::info('Invalidated navigation tags: ' . implode(', ', $event->tags), __METHOD__);
});
TagScope
navigation:menu:{uid}Menu
navigation:menu:{uid}:site:{id}Menu site
navigation:node:{id}Node
navigation:section:{uid}Dynamic entry section
navigation:categoryGroup:{uid}Dynamic category group
navigation:volume:{uid}Dynamic asset volume
navigation:productType:{uid}Dynamic product type

Menu-site invalidation also includes the shared menu tag. Use the emitted tags as invalidation information; do not assume an event only affects one site because siteId is populated.

Navigation with Blitz shows a working tag-and-listener example.