PSR-14 Events
EXT:form dispatches PSR-14 events at key points in the lifecycle of a form –
both in the backend form editor and during frontend rendering. These events
are the recommended extension point for developers; the legacy
$GLOBALS hooks have been removed.
See also
The canonical, always-up-to-date reference for all EXT:form events lives in the TYPO3 Core API documentation:
The extension documentation below provides context, usage notes and quick navigation; it intentionally avoids duplicating the full API reference.
Backend events (form editor / manager)
These events are dispatched when an editor creates, saves, duplicates or deletes a form definition in the TYPO3 backend.
| Event | When / what can be modified |
|---|---|
| BeforeFormIsCreatedEvent | Modify the form definition array and/or the persistence identifier before a new form is created in the backend. |
| BeforeFormIsSavedEvent | Modify the form definition array and/or the persistence identifier before a form is saved in the backend. |
| BeforeFormIsDuplicatedEvent | Modify the form definition array and/or the persistence identifier of the copy before a form is duplicated. |
| BeforeFormIsDeletedEvent | Dispatched before a form is deleted. Set
$event->prevent to abort the deletion (the
event implements
Stoppable). |
Frontend events (form rendering / runtime)
These events are dispatched during form rendering in the frontend.
| Event | When / what can be modified |
|---|---|
| AfterFormIsBuiltEvent | Modify the
Form object after the form factory has
finished building the complete form. |
| BeforeRenderableIsAddedToFormEvent | Modify or replace a renderable (page, section or element) before it is added to the form tree. |
| BeforeRenderableIsRemovedFromFormEvent | Dispatched before a renderable is removed from the form tree. Set
$event->prevent to abort the removal (the
event implements
Stoppable). |
| AfterCurrentPageIsResolvedEvent | Override
$event->current after the current page has been
resolved from the request, e.g. to implement conditional page-skip
logic. |
| BeforeRenderableIsValidatedEvent | Modify
$event->value before property-mapping and validation
run for each submitted form element. |
| BeforeRenderableIsRenderedEvent | Modify the renderable or the
Form just before a
renderable is output to the browser. |
| BeforeEmailFinisherInitializedEvent | Modify the options used by the
Email (e.g. recipients,
subject) before they are applied. |
| AfterFormDefinitionLoadedEvent | Dispatched by
Form after a YAML form
definition has been loaded from disk. Modify the definition globally
before it reaches the form factory. |
Registering an event listener
Register a listener via the
# PHP attribute:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Form\Event\BeforeFormIsSavedEvent;
#[AsEventListener(
identifier: 'my-extension/before-form-is-saved',
)]
final readonly class MyFormEventListener
{
public function __invoke(BeforeFormIsSavedEvent $event): void
{
// Enrich the form definition before it is persisted
$event->form['renderingOptions']['myCustomOption'] = 'value';
}
}
See also
Event dispatcher (PSR-14 events) – TYPO3 Core API documentation on how to register and implement PSR-14 event listeners.
Legacy hooks (still supported)
The following
$GLOBALS hooks are
still active in the current codebase. They have not yet been replaced by
PSR-14 events. Avoid using them in new code if a PSR-14 alternative exists.
afterFormStateInitialized
Dispatched by
Form after the
Form has been
restored from the request. At this point both the form state (submitted
values) and the static form definition are available, which makes it
suitable for enriching components that need runtime data.
Implement
\TYPO3\
and register the class:
<?php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterFormStateInitialized'][1700000000]
= \MyVendor\MyExtension\Hooks\MyAfterFormStateInitializedHook::class;
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Hooks;
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime\Lifecycle\AfterFormStateInitializedInterface;
final class MyAfterFormStateInitializedHook implements AfterFormStateInitializedInterface
{
public function afterFormStateInitialized(FormRuntime $formRuntime): void
{
// Access $formRuntime->getFormState() here
}
}
buildFormDefinitionValidationConfiguration
Used when a custom form editor inspector editor does not declare its
writable property paths via the standard YAML configuration (e.g.
property). Implement
add to
return additional
Validation objects that tell the backend form
editor which properties may be written.
Register the hook class:
<?php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['buildFormDefinitionValidationConfiguration'][]
= \MyVendor\MyExtension\Hooks\MyValidationConfigurationHook::class;
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Hooks;
use TYPO3\CMS\Form\Domain\Configuration\FormDefinition\Validators\ValidationDto;
final class MyValidationConfigurationHook
{
/**
* @return ValidationDto[]
*/
public function addAdditionalPropertyPaths(ValidationDto $validationDto): array
{
$textDto = $validationDto->withFormElementType('Text');
return [
$textDto->withPropertyPath('properties.my.custom.property'),
];
}
}