---
title: "Developer"
manual: "Ai3 Summary"
version: "0.9"
permalink: "https://docs.typo3.org/permalink/wegewerk/ai3_summary:developer@0.9"
source: "Developer/Index.rst"
rendered: "2026-10-23T16:31:11+00:00"
---

# Developer {#developer}

## Architecture {#developer-architecture}

Ai3 Summary follows the *Ai3 Suite* capability pattern provided by
[`wegewerk/ai3_core`](https://packagist.org/packages/wegewerk/ai3_core):

-   A **Capability** class registers the feature under a unique key.
-   An **Endpoint** class implements the ZAK-AI API call.
-   A **FormEngine element** renders the backend widget.
-   A **backend AJAX controller** handles the generation request.

## PHP API {#developer-php-api}

### ArticlesummaryCapability {#developer-articlesummary-capability}

-   **class ArticlesummaryCapability**

    -   *Fully qualified name:* `\Wegewerk\Ai3Summary\Domain\Capabilities\ArticlesummaryCapability`

    Extends `Wegewerk\Ai3Core\Domain\Capabilities\Capability`. Registered
    via `Configuration/Services.yaml` with the following wiring:

    -   `$key`: `articlesummary`
    -   `$title`: `Article Summary`
    -   `$endpoint`: `ZakAiSummary`
    -   Tagged as `ai3.capability`

### ZakAiSummary {#developer-zakai-summary}

-   **class ZakAiSummary**

    -   *Fully qualified name:* `\Wegewerk\Ai3Summary\Api\ZakAiSummary`

    Extends `Wegewerk\Ai3Core\Api\AbstractZakAiEndpoint` (implementing
    `ZakAiEndpointInterface`). Wraps `ZakAiClient` to call the
    ZAK-AI `bulletpoints` REST endpoint.

    -   **generate(array $options = \[\])**

        Sends page content to the ZAK-AI API and returns the generated
        bullet-point summary string.

        -   *param array $options:*

            Associative array of options:
             *\`\`text\`\` (string, required): The page content text to summarise.*
             `language` (string, optional): The target language for the summary (default: 'de').

        -   *returntype:* string

### ArticlesummaryController {#developer-ajax-controller}

-   **class ArticlesummaryController**

    -   *Fully qualified name:* `\Wegewerk\Ai3Summary\Controller\Ajax\ArticlesummaryController`

    Backend AJAX controller (`#[AsController]`), extends
    `Wegewerk\Ai3Core\Controller\Ajax\AbstractAjaxController`.

    -   **getArticlesummary(ServerRequestInterface $request)**

        Handles the AJAX generation request.

        1.  Reads `page_id` and `language` from the POST body.
        1.  Fetches all page content via `PagesRepository::getPageContent()`.
        1.  Calls `ArticlesummaryCapability` endpoint to generate the summary.
        1.  Returns a JSON response with `summary`, `source`, and
            `type: 'summary'` on success, or an error JSON on failure.

        -   *returntype:* ResponseInterface

## FormEngine integration {#developer-form-engine}

The custom FormEngine node `ai3SummaryElement` is registered in
`ext_localconf.php`:

**ext_localconf.php -- FormEngine node registration**

```php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1759225980] = [
    'nodeName' => 'ai3SummaryElement',
    'priority' => 40,
    'class' => \Wegewerk\Ai3Summary\FormEngine\Ai3SummaryElement::class,
];
```

The element is added to the `tt_content` TCA via
`Configuration/TCA/Overrides/tt_content_summary.php` as a column of
type `user` with `renderType: ai3SummaryElement`.

-   **class Ai3SummaryElement**

    -   *Fully qualified name:* `\Wegewerk\Ai3Summary\FormEngine\Ai3SummaryElement`

    Extends `TYPO3\CMS\Backend\Form\Element\AbstractFormElement`. Renders
    a `<div data-ai3="ai3-summary-container">` with `data-page-id` and
    `data-record-uid` attributes. The Lit-HTML `SummaryApp` mounts into
    the inner `<div data-ai3="ai3-summary-app">`.

## AJAX route {#developer-ajax-route}

The backend AJAX route is registered in
`Configuration/Backend/AjaxRoutes.php`:

| Route name | Path | Handler |
| --- | --- | --- |
| `ai3_articlesummary` | `/ai3/articlesummary` | `ArticlesummaryController::getArticlesummary` |

**Request** (POST, JSON body):

**AJAX request body**

```json
{
    "page_id": 42,
    "language": "en"
}
```

**Response** (success):

**AJAX success response**

```json
{
    "summary": "• Point one\n• Point two",
    "source": "articlesummary",
    "type": "summary"
}
```

## JavaScript modules {#developer-javascript}

JavaScript modules are registered via `Configuration/JavaScriptModules.php`
under the `@wegewerk/Ai3Summary/` import map prefix.

-   **\`\`@wegewerk/Ai3Summary/ai3api\`\`** -- `Ai3Api` class with
    `getArticlesummary(pageId, language)` that POSTs to the AJAX route
    via TYPO3's `AjaxRequest`.
-   **\`\`@wegewerk/Ai3Summary/summary\`\`** -- Lit-HTML `SummaryApp` that
    renders the backend widget, handles the button click, calls `Ai3Api`,
    and writes the result into the `bodytext` field (CKEditor 5 and
    CKEditor 4 fallback supported).

## Event listener {#developer-event-listener}

-   **class AfterFormEnginePageInitializedEventListener**

    -   *Fully qualified name:* `\Wegewerk\Ai3Summary\EventListener\AfterFormEnginePageInitializedEventListener`

    Listens to `AfterFormEnginePageInitializedEvent` (`#[AsEventListener]`).
    Adds the extension's `locallang.xlf` as an inline language label file
    to the `PageRenderer`, making all translation keys available to
    JavaScript.
