Event Hooks

In the previous Plugin Tutorial chapter, you might have noticed that our plugin logic was encompassed in two methods. Each of these methods onPluginsInitialized and onPageInitialized correspond to event hooks that are available throughout the Grav life cycle.

To fully harness the power of Grav plugins you need to know which event hooks are available, in what order are these hooks called, and what is available during these calls. The event hooks have a direct relationship to the overall Grav Lifecycle.

Event Order

Most events within Grav fire in a specific order and it is important to understand this order if you are creating plugins:

  1. onFatalException (no order, can occur anytime)
  2. PluginsLoadedEvent class (1.7)
  3. PluginsLoadedEvent class (1.7)
  4. onPluginsInitialized
  5. FlexRegisterEvent class (1.7)
  6. onThemeInitialized
  7. onRequestHandlerInit (1.6)
  8. onTask (1.6)
    1. onTask.{task}
  9. onAction (1.6)
    1. onAction.{action} (1.6)
  10. onBackupsInitialized
  11. onSchedulerInitialized (1.6)
  12. onAssetsInitialized
  13. onTwigTemplatePaths
  14. onTwigLoader
  15. onTwigInitialized
  16. onTwigExtensions
  17. onBuildPagesInitialized (once when pages are reprocessed)
    1. onPageProcessed (each page not cached yet)
    2. onFormPageHeaderProcessed (1.6) (each page not cached yet)
    3. onFolderProcessed (for each folder found)
  18. onPagesInitialized
  19. onPageInitialized
    1. onPageContentRaw (each page not cached yet)
    2. onMarkdownInitialized
    3. onPageContentProcessed (each page not cached yet)
    4. onPageContent (called first time Page::content() is called even when cached)
  20. onPageNotFound
  21. onPageAction (1.6)
    1. onPageAction.{action} (1.6)
  22. onPageTask (1.6)
    1. onPageTask.{task} (1.6)
  23. onTwigPageVariables (each page not cached yet)
  24. onHttpPostFilter (1.5.2)
  25. onTwigSiteVariables
  26. onCollectionProcessed (when collection is requested)
  27. onOutputGenerated
  28. onPageHeaders
  29. onOutputRendered
  30. onShutdown

Misc events:

  1. onBlueprintCreated
  2. onTwigTemplateVariables
  3. onTwigStringVariables
  4. onBeforeDownload
  5. onPageFallBackUrl
  6. onMediaLocate
  7. onGetPageBlueprints
  8. onGetPageTemplates
  9. onFlexObjectRender (1.6)
  10. onFlexCollectionRender (1.6)
  11. onBeforeCacheClear
  12. onImageMediumSaved (ImageFile)
  13. onAfterCacheClear (1.7)
  14. onHttpPostFilter (1.7)
  15. PermissionsRegisterEventclass (1.7)

Core Grav Event Hooks

There are several core Grav event hooks that are triggered during the processing of a page:

onFatalException

This is an event that can be fired at any time if PHP throws a fatal exception. This is currently used by the problems plugin to handle displaying a list of potential reasons why Grav throws the fatal exception.

onPluginsInitialized

This is the first plugin event available. At this point the following objects have been initiated:

  • Uri
  • Config
  • Debugger
  • Cache
  • Plugins

A plugin will not be loaded at all if the enabled: false configuration option has been set for that particular plugin.

onAssetsInitialized

The event indicates the assets manager has been initialized and is ready for assets to be added and managed.

onPagesInitialized

This event signifies that all the pages in Grav's user/pages folder have been loaded as objects and are available in the Pages object.

onPageNotFound

This is an event that can be fired if an expected page is not found. This is currently used by the error plugin to display a pretty 404 error page.

onPageInitialized

The current page as requested by a URL has been loaded into the Page object.

onOutputGenerated

The output has been processed by the Twig templating engine and is now just a string of HTML.

onPageHeaders

Allows the manipulation of the page headers object.

onOutputRendered

The output has been fully processed and sent to the display.

onShutdown

A new and very powerful event that lets you perform actions after Grav has finished processing and the connection to the client has been closed. This is particularly useful for performing actions that don't need user interaction and potentially could impact performance. Possible uses include user tracking and jobs processing.

onBeforeDownload

This new event passes in an event object that contains a file. This event can be used to perform logging, or grant/deny access to download said file.

onGetPageTemplates

This event enables plugins to provide their own templates in addition to the ones gathered from the theme's directory structure and core. This is especially useful if you wish the plugin to provide its own template.

Example

/**
 * Add page template types.
 */
public function onGetPageTemplates(Event $event)
{
    /** @var Types $types */
    $types = $event->types;
    $types->register('downloads');
}

This allows a plugin to register a template (that it might provide) so that it shows up in the dropdown list of page template types (like when editing a page). In the example above, a template type of downloads is added as there is a downloads.html.twig file in the downloads directory.

onGetPageBlueprints

This event, like onGetPageTemplates enables the plugin to provide its own resources in addition to core and theme-specific ones. In this case, it's blueprints.

Example

$scanBlueprintsAndTemplates = function () use ($grav) {
    // Scan blueprints
    $event = new Event();
    $event->types = self::$types;
    $grav->fireEvent('onGetPageBlueprints', $event);

    self::$types->scanBlueprints('theme://blueprints/');

    // Scan templates
    $event = new Event();
    $event->types = self::$types;
    $grav->fireEvent('onGetPageTemplates', $event);

    self::$types->scanTemplates('theme://templates/');
};

In this example, we are using both the onGetPageTemplates and onGetPageBlueprints hooks to make these plugin-provided resources (templates and blueprints) available to Grav for inheritance and other uses.

Twig Event Hooks

Twig has its own set of event hooks.

onTwigTemplatePaths

The base locations for template paths have been set on the Twig object. If you need to add other locations where Twig will search for template paths, this is the event to use.

Example

/**
 * Add template directory to twig lookup path.
 */
 public function onTwigTemplatePaths()
 {
     $this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
 }

onTwigInitialized

The Twig templating engine is now initialized at this point.

onTwigExtensions

The core Twig extensions have been loaded, but if you need to add your own Twig extension, you can do so with this event hook.

onTwigPageVariables

Where Twig processes a page directly, i.e. when you set process: twig: true in a page's YAML headers. This is where you should add any variables to Twig that need to be available to Twig during this process.

onTwigSiteVariables

Where Twig processes the full site template hierarchy. This is where you should add any variables to Twig that need to be available to Twig during this process.

Collection Event Hooks

onCollectionProcessed

If you need to manipulate a collection after it has been processed this is the time to do it.

Page Event Hooks

onBuildPagesInitialized

This event is triggered once when pages are going to be reprocessed. This typically happens if the cache has expired or needs refreshing. This is a useful event to use for plugins that need to manipulate content and cache the results.

onBlueprintCreated

This is used for processing and handling forms.

onPageContentRaw

After a page has been found, header processed, but content not processed. This is fired for every page in the Grav system. Performance is not a problem because this event will not run on a cached page, only when the cache is cleared or a cache-clearing event occurs.

onPageProcessed

After a page is parsed and processed. This is fired for every page in the Grav system. Performance is not a problem because this event will not run on a cached page, only when the cache is cleared or a cache-clearing event occurs.

onMarkdownInitialized

Called when Markdown has been initialized. Allows to override the default Parsedown processing implementation. See an usage example on the PR that introduced it.

onPageContentProcessed

This event is fired after the page's content() method has processed the page content. This is particularly useful if you want to perform actions on the post-processed content but ensure the results are cached. Performance is not a problem because this event will not run on a cached page, only when the cache is cleared or a cache-clearing event occurs.

onFolderProcessed

After a folder is parsed and processed. This is fired for every folder in the Grav system. Performance is not a problem because this event will not run on a cached page, only when the cache is cleared or a cache-clearing event occurs.

onPageFallBackUrl

If a route is not recognized as a page, Grav tries to access a page media asset. The event is fired as soon as the procedure begins, so plugins can hook and provide additional functionality.

onMediaLocate

Adds support for custom media locations for excerpts.

onTwigLoader

Adds support for use of namespaces in conjunction with two new methods in Twig class: Twig::addPath($path, $namespace) and Twig::prependPath($path, $namespace).

Found errors? Think you can improve this documentation? Simply click the Edit link at the top of the page, and then the icon on Github to make your changes.

Results