---
title: "PSR-14 events"
manual: "schema"
version: "4.4"
permalink: "https://docs.typo3.org/permalink/brotkrueml/schema:events@4.4"
source: "Developer/Events.rst"
rendered: "2026-09-28T16:49:37+00:00"
---

# PSR-14 events {#events}

Target group: **Developers**

**Table of Contents**

-   [Introduction](https://docs.typo3.org/permalink/brotkrueml/schema:introduction@4.4)
-   [Render additional types](https://docs.typo3.org/permalink/brotkrueml/schema:render-additional-types@4.4)
-   [Prevent embedding of markup](https://docs.typo3.org/permalink/brotkrueml/schema:prevent-embedding-of-markup@4.4)

## Introduction {#introduction}

You can enhance the functionality in the schema extension with PSR-14 event
listeners. An event listener receives an event that provides methods for
retrieving and setting dedicated properties.

> [!NOTE]
> **See also**
>
> You can find more information about PSR-14 events in the blog article
> [PSR-14 Events in TYPO3](https://usetypo3.com/psr-14-events.html) and the official [TYPO3 documentation](https://docs.typo3.org/m/typo3/reference-coreapi/14.3/en-us/ApiOverview/Events/EventDispatcher/Index.html#EventDispatcher).

## Render additional types {#event-render-additional-types}

The event allows to add markup in cases where no controller is available, for
example, if you want to enrich a page with structured data depending on the
doktype of a page.

The event `\Brotkrueml\Schema\Event\RenderAdditionalTypesEvent`
provides the following methods:

-   **getRequest(): \\Psr\\Http\\Message\\ServerRequestInterface**

    Returns the PSR-7 request object.

-   **addType(TypeInterface ...$type): void**

    Add one or more type models.

-   **addMainEntityOfWebPage(TypeInterface $mainEntity): void**

    Add a [main entity](https://docs.typo3.org/permalink/brotkrueml/schema:main-entity-of-web-page@4.4).

### Example {#example}

In the following example we add structured data markup depending on the doktype
of the page:

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

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\EventListener;

use Brotkrueml\Schema\Event\RenderAdditionalTypesEvent;
use Brotkrueml\Schema\Type\TypeFactory;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Frontend\Page\PageInformation;

#[AsEventListener(
    identifier: 'my-extension/add-markup-to-article-pages',
)]
final readonly class AddMarkupToArticlePages
{
    public function __construct(
        private TypeFactory $typeFactory,
    ) {}

    public function __invoke(RenderAdditionalTypesEvent $event): void
    {
        /** @var PageInformation $pageInformation */
        $pageInformation = $event->getRequest()
            ->getAttribute('frontend.page.information');
        $page = $pageInformation->getPageRecord();
        if ($page['doktype'] !== 12345) {
            return;
        }

        // Only for doktype 12345
        $article = $this->typeFactory->create('Article');
        $article->setProperty('name', $page['title']);
        // ... and set some other properties

        $event->addType($article);
    }
}

```

The method `__invoke()` implements the logic for rendering additional
types. It receives the `RenderAdditionalTypesEvent`. You can add as many
types as you like.

## Prevent embedding of markup {#prevent-embedding-of-markup}

<!-- TODO: no Markdown rendering for "versionadded" -->

Sometimes it is required to disable the embedding of markup on certain pages.
If you have the need for that, the event
`\Brotkrueml\Schema\Event\IsMarkupToBeInjectedEvent` is your friend.
The event is stoppable: the event listener that excludes the markup from
injection is the last one called in the chain.

The event provides the following methods:

-   **getRequest(): \\Psr\\Http\\Message\\ServerRequestInterface**

    Returns the PSR-7 request object.

-   **excludeMarkupFromInjection(): void**

    Method to be called, if you want to exclude a page from embedding the markup.

### Example {#example-1}

The example excludes the markup from injection, if the page ID is 42:

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

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\EventListener;

use Brotkrueml\Schema\Event\IsMarkupToBeInjectedEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Frontend\Page\PageInformation;

#[AsEventListener(
    identifier: 'my-extension/exclude-markup-from-page-42',
)]
final readonly class ExcludeMarkupOnPage42
{
    public function __invoke(IsMarkupToBeInjectedEvent $event): void
    {
        /** @var PageInformation $pageInformation */
        $pageInformation = $event->getRequest()
            ->getAttribute('frontend.page.information');
        if ($pageInformation->getId() === 42) {
            $event->excludeMarkupFromInjection();
        }
    }
}

```
