---
title: "ModifyPluginViewEvent"
manual: "Academic Base"
version: "3.0"
permalink: "https://docs.typo3.org/permalink/fgtclb/academic-base:developers-event-modify-plugin-view-event@3.0"
source: "Developers/Events/ModifyPluginViewEvent.rst"
rendered: "2026-10-26T17:54:57+00:00"
---

# ModifyPluginViewEvent {#developers-event-modify-plugin-view-event}

`\FGTCLB\AcademicBase\Event\ModifyPluginViewEvent` 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](https://docs.typo3.org/permalink/fgtclb/academic-base:developers-extension-points-not-api@3.0).

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](https://docs.typo3.org/permalink/fgtclb/academic-base:when-it-is-dispatched@3.0)
-   [What a listener reads and changes](https://docs.typo3.org/permalink/fgtclb/academic-base:what-a-listener-reads-and-changes@3.0)
-   [Example](https://docs.typo3.org/permalink/fgtclb/academic-base:example@3.0)
-   [Rules and pitfalls](https://docs.typo3.org/permalink/fgtclb/academic-base:rules-and-pitfalls@3.0)
-   [Introduced in](https://docs.typo3.org/permalink/fgtclb/academic-base:introduced-in@3.0)

## When it is dispatched {#developers-event-modify-plugin-view-event-dispatch}

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 | `getControllerExtensionName()` | Plugins, by the name `getPluginName()` returns |
| --- | --- | --- |
| [academic_bite_jobs](https://docs.typo3.org/p/fgtclb/academic-bite-jobs/main/en-us/Developers/Events/ModifyPluginViewEvent.html) | `AcademicBiteJobs` | `List` |
| [academic_contacts4pages](https://docs.typo3.org/p/fgtclb/academic-contacts4pages/main/en-us/Developers/Events/ModifyPluginViewEvent.html) | `AcademicContacts4pages` | `List` |
| [academic_jobs](https://docs.typo3.org/p/fgtclb/academic-jobs/main/en-us/Developers/Events/ModifyPluginViewEvent.html) | `AcademicJobs` | `List`, `Detail`, `NewJobForm` |
| [academic_partners](https://docs.typo3.org/p/fgtclb/academic-partners/main/en-us/Developers/Events/ModifyPluginViewEvent.html) | `AcademicPartners` | `List`, `Map`, `PartnershipsList`, `PartnershipsTeaser` |
| [academic_persons](https://docs.typo3.org/p/fgtclb/academic-persons/main/en-us/Developers/Events/ModifyPluginViewEvent.html) | `AcademicPersons` | `List`, `ListAndDetail`, `Detail`, `Card`, `SelectedProfiles`, `SelectedContracts` |
| [academic_programs](https://docs.typo3.org/p/fgtclb/academic-programs/main/en-us/Developers/Events/ModifyPluginViewEvent.html) | `AcademicPrograms` | `ProgramList`, `ProgramFinder`, `ProgramDetails` |
| [academic_projects](https://docs.typo3.org/p/fgtclb/academic-projects/main/en-us/Developers/Events/ModifyPluginViewEvent.html) | `AcademicProjects` | `ProjectList`, `ProjectListSingle` |

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 {#what-a-listener-reads-and-changes}

| Method | Returns |
| --- | --- |
| `getView()` | The view the action renders. A variable assigned to it with `assign()` or `assignMultiple()` reaches the templates, partials and sections of the plugin. Nothing has to be handed back. |
| `getPluginControllerActionContext()` | The context of the rendering, typed against `\FGTCLB\AcademicBase\Domain\Model\Dto\PluginControllerActionContextInterface`, 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 |
| --- | --- |
| `getControllerExtensionName()` | The extension name of the plugin, `AcademicPersons` for example. |
| `getControllerExtensionKey()` | The extension key of the plugin, `academic_persons` for example. |
| `getPluginName()` | The name the plugin is registered with, see the table above. |
| `getControllerName()`, `getControllerObjectName()` | The short name and the class name of the controller. |
| `getActionName()` | The action that renders, `list` or `detail` for example. |
| `getSettings()` | The settings the action rendered with: the plugin settings of the content element merged over the TypoScript settings, after the action settled them. |
| `getRequest()`, `getExtbaseRequestParameters()` | The request of the rendering and its Extbase parameters. |
| `getSite()`, `getLanguage()` | The site and the site language of the request. |
| `getContentObjectRenderer()` | The content object of the content element, which carries its record in `$data`. |
| `getApplicationType()` | Frontend or backend. |

Every getter that can lack its value returns `null` instead of failing.
`getApplicationType()` 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 {#developers-event-modify-plugin-view-event-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:

**EXT:my_extension/Classes/EventListener/AddContactFormPage.php**

```php
<?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](https://docs.typo3.org/permalink/fgtclb/academic-base:developers-extension-points-plugin-view@3.0).

## Rules and pitfalls {#developers-event-modify-plugin-view-event-rules}

-   **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 `after` argument of
    `#[AsEventListener]`.

## Introduced in {#introduced-in}

-   [Feature: One event to add variables to every plugin view](https://docs.typo3.org/permalink/fgtclb/academic-base:feature-modify-plugin-view-event@3.0)
-   [Important: The events of one plugin rendering share their context](https://docs.typo3.org/permalink/fgtclb/academic-base:important-1790607225@3.0)
-   [Important: The plugin action context never fails on the content object](https://docs.typo3.org/permalink/fgtclb/academic-base:important-plugin-controller-action-context-content-object@3.0) and
    [Important: The plugin action context never fails on the site or the language](https://docs.typo3.org/permalink/fgtclb/academic-base:important-ace-748-academic-base@3.0) (2.4), which made the getters of
    the context return `null` rather than fail
