ModifyPluginViewEvent
\FGTCLB\ hands a listener the
view of an academic plugin right before it renders, so the listener can assign
further variables to it. A template override then renders them. It is the
supported way to bring one more value into the templates of a plugin, the uid
of a page a template links to or a value computed from the records the plugin
shows, without copying, subclassing or XCLASSing a plugin controller. The
controllers are
final
, see
What is not public API.
This extension owns the event and dispatches it nowhere itself. The plugins of seven academic extensions dispatch it. Each of them documents what it passes in, with an example that fits its plugins.
When it is dispatched
Every action of a plugin that renders a view dispatches the event once, after it assigned its own variables and right before it renders, including the rendering of an empty state, a list without results for example. An action that answers with a redirect, a list filter that is submitted or a job form that is saved, renders nothing and dispatches nothing.
| Extension |
get |
Plugins, by the name
get returns |
|---|---|---|
| academic_bite_jobs | Academic | List |
| academic_contacts4pages | Academic | List |
| academic_jobs | Academic | List, Detail, New |
| academic_partners | Academic | List, Map, Partnerships, Partnerships |
| academic_persons | Academic | List, List, Detail, Card,
Selected, Selected |
| academic_programs | Academic | Program, Program, Program |
| academic_projects | Academic | Project, Project |
The profile editing of academic_persons_edit does not dispatch the event. Its views are driven by a script that saves through endpoints of its own, and every write of it is offered to an event of its own instead. The content element of academic_study_plan is no Extbase plugin and does not dispatch it either.
What a listener reads and changes
| Method | Returns |
|---|---|
get | The view the action renders. A variable assigned to it with
assign or
assign reaches the templates,
partials and sections of the plugin. Nothing has to be handed back. |
get | The context of the rendering, typed against
\FGTCLB\,
for reading. See below. |
The context tells a listener which plugin and which action it is called for, and hands over what the action rendered with:
| Method of the context | Returns |
|---|---|
get | The extension name of the plugin, Academic for example. |
get | The extension key of the plugin, academic_ for example. |
get | The name the plugin is registered with, see the table above. |
get,
get | The short name and the class name of the controller. |
get | The action that renders, list or detail for example. |
get | The settings the action rendered with: the plugin settings of the content element merged over the TypoScript settings, after the action settled them. |
get,
get | The request of the rendering and its Extbase parameters. |
get,
get | The site and the site language of the request. |
get | The content object of the content element, which carries its
record in
$data
. |
get | Frontend or backend. |
Every getter that can lack its value returns
null
instead of failing.
get is the exception: for a request without an
application type, which only a request built by hand can be, TYPO3 raises its
own exception.
Example
A site links the detail view of every list of the academic extensions to a contact form, on a page whose uid the templates should not hard code. One listener assigns the uid to every detail view, and the template overrides of the site render the link with it:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use FGTCLB\AcademicBase\Event\ModifyPluginViewEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
final readonly class AddContactFormPage
{
private const CONTACT_FORM_PAGE_UID = 42;
#[AsEventListener(identifier: 'my-extension/add-contact-form-page')]
public function __invoke(ModifyPluginViewEvent $event): void
{
$context = $event->getPluginControllerActionContext();
$action = $context->getActionName();
if ($action !== 'detail' && $action !== 'show') {
return;
}
$event->getView()->assign('contactFormPageUid', self::CONTACT_FORM_PAGE_UID);
}
}
The detail actions of the persons plugins are named detail, those of the
job and the program details plugins show. A listener meant for one plugin
checks the extension name and the plugin name as well, because two
extensions register plugins of the same name, List for example. A further
example is part of the extension points page.
Rules and pitfalls
- The view only. The event runs after the action assigned its own variables. A listener that assigns one of them again replaces it in the view and nowhere else: the pagination, the page title and the other events of the rendering keep what the action computed. Which records a plugin shows is changed in a demand or a query event of the extension that ships the plugin, not here.
- Some variables are protected. An action may assign a variable after the event on purpose, so no listener can replace it. The validations of the job form of academic_jobs are the one case today.
- Check the plugin. One listener is called for every plugin of every dispatching extension. A listener that does not check the context assigns its variables to all of them.
- One context per rendering. The action builds its context once and
hands the same object to every event it dispatches while it renders, the
demand and list events of the same extension among them. A listener of
several of them can keep what it collects keyed by that object. Its
settings are the ones the action used, which may differ from the
{settings}in the view: Extbase assigns those before the action runs. - No order is promised between several listeners. A listener that has
to run after another one says so with the
afterargument of#.[As Event Listener]
Introduced in
- Feature: One event to add variables to every plugin view
- Important: The events of one plugin rendering share their context
- Important: The plugin action context never fails on the content object and
Important: The plugin action context never fails on the site or the language (2.4), which made the getters of
the context return
nullrather than fail