Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Events, extension points and plugins

How behavior is added to Exponential without forking it - the in-process event bus ezpEvent with notify and filter, handlers named in settings, datatypes, workflow event types, template operators, fetch functions, login…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/software-engineers/events-extension-points-and-plugins.md

On this page

Events, extension points and plugins

This page is for engineers who need to change what Exponential does without changing its code. Nearly every part of the kernel is pluggable through a setting that names a class; the in-process event bus adds hooks at fixed points of a request. The full list is Extension points at a glance and the registered points are documented in RAD extension points.

Contents

  1. The order of preference
  2. The event bus: ezpEvent
  3. Handlers named in settings
  4. Replacing a view or a module
  5. The last resort: a kernel override
  6. Rules for listeners and plugins

The order of preference

  1. A setting. Many behaviors are switches or lists already; check the shipped settings/*.ini first.
  2. A template override for presentation (The template engine and the design chain).
  3. A registered extension point: a datatype, workflow event, operator, fetch function, handler or event listener.
  4. A replaced view or module, through [RunnableSettings] or an extension module override.
  5. A kernel class override, only when nothing above fits.

The event bus: ezpEvent

ezpEvent::getInstance() (kernel/private/classes/ezpevent.php) offers two calls:

CallUse
notify( $name, $params )tell listeners that something happened
filter( $name, $value )let listeners change a value and return it

Global listeners are configured in site.ini [Event] Listeners[]=<event>@<callback>. Events the kernel emits include:

EventWhen
request/preinput, request/inputat the start of the dispatch loop
response/preoutput, response/outputoutput filters, before the response is sent
content/cache, content/cache/all, content/class/cachecontent view caches are cleared
image/removeAliasesimage variations are removed
content/edit/access, content/download/access, collaboration/item/accessaccess filters that can refuse
runnable/<kind>/before, runnable/<kind>/afteraround class-based views, commands and cronjob parts

The file marks ezpEvent as private API that may change; extensions rely on it nonetheless, so changes to it are treated as compatibility-relevant (Events and filters).

Handlers named in settings

Extension pointSettingGuide
Datatypescontent.ini [DataTypeSettings]Custom datatypes
Workflow event typesworkflow.ini [EventSettings]Writing a workflow event type
Template operators and functionssite.ini [TemplateSettings] ExtensionAutoloadPath[]Template operators
Fetch functionsthe module's function_definition.phpWriting a fetch function
Cronjob partscronjob.iniWriting a cronjob part
Notification handlersnotification.iniNotifications and mail
Content limitation handlerssee the feature pageContent limitation handlers
Cluster file handlerfile.ini [ClusteringSettings] FileHandlerScaling and clustering
Any handler named by a settingthe patternHandlers named by settings

Replacing a view or a module

  • A class-based view can be replaced through site.ini [RunnableSettings] Implementation[].
  • A whole kernel module can be replaced by an extension's module of the same name (Extension module override).

The last resort: a kernel override

A kernel class override replaces a kernel class with a copy in an extension. Every update of the kernel can then break your copy silently, so it needs a test and a note in your upgrade checklist (Kernel overrides, the last resort).

Rules for listeners and plugins

  • Registrations must be idempotent. Under Velocity a listener attached once per request in a long-lived worker accumulates (Concurrency, statics and long-lived processes).
  • Listener names should be Class::method strings so they can be configured.
  • A new class named in a shipped setting should be guarded with class_exists() where the kernel loads it.
  • Access decisions go through the access filters, never through a check of a user id.

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x