Zum Inhalt springen

KI-Übersetzung direkt im CMS: TYPO3 14, der neue Translation Wizard und Ollama

  • von

Wie der modernisierte Übersetzungs-Workflow in TYPO3 14 funktioniert – und wie wir ihn mit TranslateGemma 27b für vollautomatische KI-Übersetzungen erweitert haben.


TYPO3 14: Ein neues Kapitel für Mehrsprachigkeit

Mit TYPO3 14.3 LTS, veröffentlicht im April 2026, steht nun die langfristig unterstützte Version der 14er-Reihe bereit. Sie bündelt die seit 14.0 eingeführten Neuerungen – darunter über 2.000 Änderungen – und legt einen klaren Schwerpunkt auf die Editor-Experience, insbesondere beim Arbeiten mit mehrsprachigen Inhalten.

Das Herzstück dieser Neuerungen im Übersetzungsbereich ist Feature #108049 – Modernized Translation Workflow: Der bisherige monolithische Lokalisierungsdialog wurde vollständig durch ein schrittbasiertes Wizard-System ersetzt.

Was hat sich konkret geändert?

Vorher: Der Übersetzungsdialog war ein einfaches Modal, das nur im Modul Content > Layout (früher: Web > Page) verfügbar war – je nach Kontext mit leicht abweichendem Verhalten.

Jetzt: Ein einheitlicher, geführter Wizard öffnet sich überall im Backend, sobald eine Übersetzung angestoßen wird – egal ob in der Seitenansicht, der Listenansicht oder einem anderen Modul. Der Wizard führt Schritt für Schritt durch den Prozess und überspringt automatisch Schritte, bei denen keine Nutzereingabe nötig ist.

Zusätzlich verbessert TYPO3 14 die Sprachauswahl im Backend grundlegend: Redakteure können mehrere Sprachen gleichzeitig anzeigen, zwischen ihnen wechseln und die Auswahl bleibt konsistent zwischen Page- und List-Modul erhalten.

„The new translation system also lets developers integrate custom localization handlers, including connections to third-party translation services or AI tools.“ — TYPO3 News, Dezember 2025

Genau dieser letzte Satz war unser Startpunkt.


Die neue Handler-API: Offen für eigene Übersetzungsdienste

Technisch gesehen führt TYPO3 14 im Namespace TYPO3\CMS\Backend\Localization ein neues Interface ein: das LocalizationHandlerInterface. Wer es implementiert, erscheint im Wizard als wählbare Übersetzungsoption – gleichrangig neben der eingebauten manuellen Übersetzung.

Das Interface ist in der TYPO3-Dokumentation unter Feature #108049 beschrieben und verlangt sechs Methoden:

interface LocalizationHandlerInterface
{
    public function getIdentifier(): string;     // eindeutige ID
    public function getLabel(): string;          // Anzeigename im Wizard
    public function getDescription(): string;    // Kurzbeschreibung
    public function getIconIdentifier(): string; // TYPO3-Icon-ID
    public function isAvailable(LocalizationInstructions $instructions): bool;
    public function processLocalization(LocalizationInstructions $instructions): LocalizationResult;
}

Das DTO LocalizationInstructions enthält alle nötigen Informationen für den Handler:

final readonly class LocalizationInstructions
{
    public string $mainRecordType;  // z. B. 'pages' oder 'tt_content'
    public int    $recordUid;
    public int    $sourceLanguageId;
    public int    $targetLanguageId;
    public LocalizationMode $mode; // 'translate' oder 'copy'
    public array  $additionalData; // z. B. ausgewählte Content-Element-UIDs
}

Der Handler gibt ein LocalizationResult zurück – entweder mit Erfolg und einem Finisher (der vorgibt, was der Wizard danach tut: Redirect, Reload, oder nichts), oder mit einer Fehlerliste.

Die Registrierung erfolgt über einen Symfony-Service-Tag:

UniErfurt\OllamaTranslate\Localization\OllamaLocalizationHandler:
  tags:
    - name: backend.localization.handler

Unsere Extension: ollama_translate

Auf Basis dieser API haben wir die Extension ollama_translate entwickelt, die den HPC-Ollama-Cluster des HS-ITZ mit dem TYPO3-Übersetzungs-Wizard verbindet. Als Modell kommt TranslateGemma 27b zum Einsatz – ein auf Übersetzungsaufgaben spezialisiertes Modell auf Basis von Googles Gemma-Architektur.

Visual Portfolio, Posts & Image Gallery for WordPress

TYPO3 Backend

Der Wizard öffnet sich

Nach Bestätigung

Ablauf einer Übersetzung

Das folgende Diagramm zeigt den vollständigen Ablauf vom Klick des Redakteurs bis zum fertigen deutschen Text in der Datenbank:

sequenceDiagram
    actor Redakteur
    participant Wizard as TYPO3 Wizard
    participant Handler as OllamaLocalizationHandler
    participant DH1 as DataHandler (Anlegen)
    participant Glossar as GlossaryService
    participant DH2 as DataHandler (Befüllen)
    participant Ollama as Ollama API

    Redakteur->>Wizard: Klick „Übersetzen" (Zielsprache: DE)
    Wizard->>Redakteur: Handler-Auswahl (manuell / Ollama)
    Redakteur->>Wizard: Wählt „Ollama / TranslateGemma"
    Redakteur->>Wizard: Content-Elemente auswählen → Weiter

    Wizard->>Handler: processLocalization(instructions)

    Handler->>DH1: Records anlegen (localize/copy)
    DH1-->>Handler: neue UIDs aus copyMappingArray_merged

    loop Für jeden neu angelegten Record
        Handler->>Glossar: getRelevantTerms(text)
        Glossar-->>Handler: proper-Begriffe + term-Begriffe

        Handler->>Glossar: applyPlaceholders(text, proper)
        Glossar-->>Handler: Text mit §TERM_0§ Platzhaltern

        Handler->>Glossar: buildPromptGlossary(term)
        Glossar-->>Handler: Glossar-Block für Prompt

        Handler->>Ollama: POST /api/chat (Text + Glossar-Kontext)
        Ollama-->>Handler: übersetzte Antwort

        Handler->>Glossar: restorePlaceholders(übersetzt, map)
        Glossar-->>Handler: fertiger Zieltext

        Handler->>DH2: Übersetzung in Record schreiben
    end

    Handler-->>Wizard: LocalizationResult::success(RedirectFinisher)
    Wizard->>Redakteur: Weiterleitung zur übersetzten Seite

Kommunikation mit Ollama

Die Extension spricht den /api/chat-Endpunkt des Ollama-Clusters an – das offizielle Chat-API-Format von Ollama (Dokumentation):

$payload = [
    'model'  => 'translategemma:27b',
    'stream' => false,
    'messages' => [[
        'role'    => 'user',
        'content' => "You are a professional translator. Translate from en to de.
                      Return ONLY the translated text.
                      [Glossar-Block falls vorhanden]
                      Text: {$text}",
    ]],
];

// Ollama gibt zurück:
// { "message": { "role": "assistant", "content": "..." } }
$translation = $data['message']['content'];

Welche Felder werden übersetzt?

Der Handler liest dynamisch die TCA-Konfiguration der jeweiligen Tabelle aus und übersetzt alle Felder vom Typ input oder text, die nicht explizit mit l10n_mode: exclude ausgeschlossen sind. Das macht die Extension universell einsetzbar – für tt_content, pages und beliebige Custom-Tables.

Felder mit aktiviertem enableRichtext (RTE-Felder) werden gesondert behandelt: Die Extension zerlegt den HTML-Inhalt per DOMDocument, übersetzt nur die Textknoten und setzt das HTML anschließend wieder zusammen. Tags, Links und Struktur bleiben dabei vollständig erhalten.


Glossar: Terminologie zuverlässig steuern

Bei der Übersetzung mit KI-Modellen stellt sich schnell die Frage: Was passiert mit institutionellen Begriffen, Eigennamen oder Fachvokabular, das im Deutschen eine definierte Entsprechung haben soll? „Universität Erfurt“ darf nicht übersetzt werden, „Albergue“ soll konsistent als „Pilgerherberge“ erscheinen.

Das Problem mit naiver Glossar-Integration

Der erste Ansatz – Begriffe einfach per Platzhalter ersetzen und nach der Übersetzung wieder einsetzen – führt bei flektierten Sprachen wie Deutsch schnell zu Problemen:

„die §TERM_0§“ → „die Jakobsweg“

Das Modell hat den Artikel korrekt auf das Originalwort abgestimmt, aber nach der Platzhalter-Restaurierung passt er nicht mehr zum eingesetzten Begriff. Besonders bei Pluralformen und Kasus-Flexion wird das schnell unleserlich.

Die Lösung: zwei Strategien je nach Begriffstyp

Die Extension unterscheidet deshalb zwischen zwei Klassen von Glossareinträgen:

proper – Eigennamen und unveränderliche Begriffe Institutionsnamen, Zeremonienbezeichnungen, Dokumentennamen in der Originalsprache – alles was im Zieltext exakt so erscheinen soll wie in der Quelle. Diese Begriffe werden per Platzhalter geschützt, Ollama sieht sie gar nicht, und nach der Übersetzung werden sie 1:1 wieder eingesetzt.

term – Fachbegriffe mit Flexionsbedarf Alles was im Deutschen flektiert wird: Personen, Ortstypen, Routen, Fachbegriffe. Diese Begriffe werden nicht als Platzhalter behandelt, sondern als Glossar-Kontext direkt in den Prompt übergeben:

You are a professional translator. Translate from en to de.
Rules:
1. Return ONLY the translated text.
2. For the following terms, use the given translations and adapt them
   grammatically (case, plural, gender) as needed:
  Pilgrim = Pilger
  Albergue = Pilgerherberge
  Camino de Santiago = Jakobsweg

Text to translate:
The Pilgrim walks through many Albergues on the Camino de Santiago.

Ollama kann jetzt selbst entscheiden: „des Pilgers“, „die Pilgerherbergen“, „dem Jakobsweg“ – grammatikalisch korrekt je nach Kontext.

Skalierung auf 300+ Einträge

Ein institutionelles Glossar mit 300 Einträgen kann nicht pauschal in jeden Prompt kopiert werden – das würde das Kontextfenster des Modells belasten und die Übersetzungsqualität verschlechtern. Die Extension löst das durch einen Vorfilter-Schritt: Vor jeder Übersetzung wird der Text gescannt und nur die tatsächlich vorkommenden Begriffe herausgefiltert. Bei einem typischen Content-Element sind das 5–15 Treffer aus dem Gesamtglossar.

Das CSV-Format

source,target,type
Botafumeiro,Botafumeiro,proper
Credencial del Peregrino,Credencial del Peregrino,proper
Universität Erfurt,Universität Erfurt,proper
Camino de Santiago,Jakobsweg,term
Pilgrim,Pilger,term
Pilgrims,Pilger,term
Albergue,Pilgerherberge,term
Albergues,Pilgerherbergen,term
Pilgrim's Mass,Pilgermesse,term

Das Ergebnis mit dieser Strategie – hier am Beispiel des Jakobsweg-Testtexts:

„Der Jakobsweg ist eine der berühmtesten Pilgerrouten der Welt und zieht jedes Jahr Hunderttausende von Pilgern an. […] Unterwegs sammeln die Pilger Stempel in ihrem Pilgerausweis (bekannt als Credencial del Peregrino) in Kirchen, Pilgerherbergen und Cafés […]“

Grammatik stimmt, Eigennamen bleiben erhalten, Fachbegriffe sind korrekt flektiert.


Stolpersteine – damit ihr es einfacher habt

Die Entwicklung war kein gerader Weg. Hier die wichtigsten Fallstricke:

1. Falscher Namespace – der häufigste Fehler

Das Interface LocalizationHandlerInterface gibt es in TYPO3 zweimal. Eines im Core-Namespace für völlig andere Zwecke, eines neu in Backend. Der Handler erscheint im Wizard überhaupt nicht, wenn der falsche Namespace importiert wird – ohne jede Fehlermeldung:

// FALSCH – bitte nicht:
use TYPO3\CMS\Core\Localization\LocalizationHandlerInterface;

// RICHTIG:
use TYPO3\CMS\Backend\Localization\LocalizationHandlerInterface;

2. Autoconfiguration funktioniert nicht – expliziter Tag nötig

Die offizielle Dokumentation beschreibt, Handler würden per Autoconfiguration automatisch erkannt. In TYPO3 14.3 stimmt das nicht. Der LocalizationHandlerRegistry sammelt Handler ausschließlich über den Tag backend.localization.handler, der explizit gesetzt werden muss. Ein Wildcard-Scan (resource: '../Classes/*') reicht nicht – und verursacht zudem ein Henne-Ei-Problem beim composer dumpautoload, weil Symfony versucht alle Klassen zu laden bevor der Autoloader fertig ist.

3. LocalizationInstructions enthält keine Sprach-Objekte

Ich hatte erwartet, dort SiteLanguage-Objekte zu finden. Tatsächlich gibt es nur Integer-IDs. Der ISO-Code muss über den SiteFinder aufgelöst werden – und die Methode heißt nicht getTwoLetterIsoCode() (existiert in TYPO3 14 nicht mehr), sondern:

$language->getLocale()->getLanguageCode();

4. LocalizationResult::success() braucht einen Finisher

// FALSCH – Methode existiert nicht:
LocalizationResult::createSuccess($data)

// RICHTIG – ein Finisher ist Pflicht:
LocalizationResult::success(new RedirectLocalizationFinisher($url))
LocalizationResult::success(new ReloadLocalizationFinisher())

5. Der Handler erstellt keine Records – DataHandler muss zweimal laufen

Der Handler ist nicht dafür gedacht, Records zu erstellen. Das macht TYPO3 selbst. Der Handler bekommt erst danach die Kontrolle:

  1. Erst Records per DataHandler anlegen (localize/copy)
  2. Die UIDs der neu angelegten Records aus $dataHandler->copyMappingArray_merged auslesen
  3. Dann diese Records mit den Übersetzungen per zweitem DataHandler-Aufruf befüllen

6. Ollama-Response-Format ≠ OpenAI-Format

// OpenAI: choices[0].message.content
// Ollama /api/chat:
{ "message": { "role": "assistant", "content": "..." } }

7. DDEV: Alles im Container ausführen

composer dumpautoload auf dem Host aktualisiert den Autoloader des Host-Systems – nicht den des DDEV-Containers. Alle Befehle müssen mit ddev exec bzw. ddev composer laufen.


Ergebnis

Die Extension ist produktiv einsetzbar. Redakteure können im TYPO3-Backend auf Knopfdruck vollautomatische Übersetzungen mit TranslateGemma 27b auslösen – direkt aus dem neuen Wizard, ohne externe Tools, ohne Medienbruch. Das Glossar-System stellt sicher dass institutionelle Terminologie konsistent und grammatikalisch korrekt übernommen wird.

Für alle die selbst einen TYPO3-14-Lokalisierungs-Handler bauen möchten: Das Sequence-Diagramm oben zeigt den Ablauf, die Stolpersteine ersparen einige Stunden Debugging.


Quellen & Links

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert