Technisch

Content Blocks in TYPO3 14 — Der neue Weg für Custom Content Elements

Wer Custom Content Elements in TYPO3 klassisch anlegt, pflegt pro Element mindestens 6–8 Dateien — TCA, TypoScript, Sprachdateien, Templates. Content Blocks in TYPO3 14 lösen dieses Problem mit einem deklarativen Ansatz: Eine config.yaml definiert die Felder, ein Fluid-Template rendert die Ausgabe, und TYPO3 generiert den Rest automatisch. Das reduziert den Boilerplate-Aufwand auf 2–3 Dateien pro Element. Content Blocks eignen sich für TYPO3-Integratoren und Agentur-Teams, die regelmäßig projektspezifische Content Elements anlegen.

Hände stecken zwei modulare Bausteine über einem Schreibtisch zusammen, ein Baustein violett

Wer Custom Content Elements in TYPO3 klassisch anlegt, pflegt pro Element mindestens 6–8 Dateien — TCA, TypoScript, Sprachdateien, Templates. Content Blocks in TYPO3 14 lösen dieses Problem mit einem deklarativen Ansatz: Eine config.yaml definiert die Felder, ein Fluid-Template rendert die Ausgabe, und TYPO3 generiert den Rest automatisch. Das reduziert den Boilerplate-Aufwand auf 2–3 Dateien pro Element. Content Blocks eignen sich für TYPO3-Integratoren und Agentur-Teams, die regelmäßig projektspezifische Content Elements anlegen.

Warum Content Blocks in TYPO3 14 das CE-Modell vereinfachen

Ein Custom Content Element im klassischen TYPO3-Workflow erfordert mehrere Konfigurationsschritte: TCA-Definition in tt_content.php, Registrierung in ext_localconf.php, TypoScript-Setup für das Rendering, ein Fluid-Template, optional eine Backend-Preview und die zugehörigen Sprachdateien. Bei jedem neuen Element wiederholt sich dieser Ablauf — mit viel Copy-Paste und hohem Fehlerpotenzial.

Content Blocks — eines der zentralen neuen Features im TYPO3 14 Upgrade-Guide — kapseln alles in einem einzigen Verzeichnis. Die Felddefinition passiert in einer config.yaml, das Rendering in frontend.html. TYPO3 liest die YAML-Datei ein, generiert das TCA und registriert den Content Type (CType) automatisch. Die Struktur ist standardisiert, projektübergreifend wiederverwendbar und für neue Teammitglieder sofort verständlich.

Content Block in TYPO3 14 erstellen — Schritt für Schritt

Ein Content Block besteht aus einem Verzeichnis mit fester Struktur. In diesem Projekt liegen Content Blocks unter packages/cb/ContentBlocks/. Jeder Block folgt dem gleichen Aufbau.

Verzeichnisstruktur

plaintext
packages/cb/ContentBlocks/hero-banner/
├── assets/
│   └── icon.svg
├── language/
│   └── labels.xlf
├── templates/
│   ├── frontend.html
│   └── backend-preview.html
└── config.yaml
Verzeichnisstruktur eines Content Blocks

Die config.yaml ist die zentrale Datei. Sie definiert den Namen des Blocks und alle Felder, die im Backend-Formular erscheinen. Der Name folgt dem Format vendor/block-name und muss projektübergreifend eindeutig sein.

Felder definieren

Content Blocks unterstützen alle gängigen Feldtypen:

  • Text, Textarea, Email, Number — einfache Eingabefelder
  • Link, File, Category — strukturierte Referenzen
  • Select, Radio, Checkbox — Auswahlfelder
  • Collection — wiederholbare Feldgruppen
  • FlexForm — flexible Inhaltskonfiguration

Bestehende Felder wie header oder bodytext könnt ihr mit useExistingField: true wiederverwenden, statt neue Datenbankfelder anzulegen.

Frontend-Template

Das frontend.html ist ein normales Fluid-Template. Alle in der config.yaml definierten Felder sind über das {data}-Objekt verfügbar. Der Feldname entspricht dem identifier aus der YAML-Datei.

Backend-Preview

Die backend-preview.html definiert, wie das Element im TYPO3-Backend dargestellt wird. Sie nutzt das Layout Preview und die Sections Header, Content und Footer. Die Backend-Preview ist optional — ohne sie zeigt TYPO3 nur den CType-Identifier als Vorschau, was für Redakteure beim Befüllen von Seiten uneindeutig ist.

yaml
name: vibe/hero-banner
fields:
  - identifier: header
    useExistingField: true
  - identifier: subtitle
    type: Textarea
    max: 200
  - identifier: hero_image
    type: File
    allowed: ['image/jpeg', 'image/png', 'image/webp']
    minitems: 1
    maxitems: 1
  - identifier: cta_link
    type: Link
  - identifier: cta_text
    type: Text
    max: 50
    required: true
Deklarative Felddefinition — TYPO3 generiert TCA und Datenbankfelder automatisch
html
<section class="hero-banner relative overflow-hidden">
    <f:if condition="{data.hero_image}">
        <f:image image="{data.hero_image}" alt="{data.header}" class="w-full h-[60vh] object-cover" />
    </f:if>
    <div class="absolute inset-0 flex flex-col items-center justify-center text-center">
        <h1 class="text-4xl md:text-6xl font-bold text-white">
            {data.header}
        </h1>
        <f:if condition="{data.subtitle}">
            <p class="mt-4 text-lg text-white/80 max-w-2xl">
                {data.subtitle}
            </p>
        </f:if>
        <f:if condition="{data.cta_link}">
            <f:link.typolink parameter="{data.cta_link}" class="mt-8 inline-block rounded-md bg-purple-600 px-6 py-3 text-white hover:bg-purple-700">
                {data.cta_text}
            </f:link.typolink>
        </f:if>
    </div>
</section>
Fluid-Template mit Zugriff auf die Felder über das data-Objekt

Content Blocks vs. klassische Content Elements — Wann was einsetzen?

Content Blocks sind nicht für jeden Anwendungsfall die richtige Wahl. Die Entscheidung hängt von der Komplexität des Elements und dem Bedarf an individueller Geschäftslogik ab.

Wann Content Block, wann Extbase-Plugin?

  • Wenn euer Element nur Felder im Backend und ein Fluid-Template im Frontend braucht → Content Block verwenden.
  • Wenn euer Element eine eigene Datenbank-Tabelle mit Repository-Abfragen oder komplexe Geschäftslogik benötigt → Extbase-Plugin verwenden.
  • Wenn euer Element Daten aus externen APIs lädt oder aufwendige Berechnungen durchführt → Extbase-Plugin oder DataProcessor verwenden.
  • Wenn ihr ein einfaches Element schnell in mehreren Projekten wiederverwenden wollt → Content Block verwenden.
  • Wenn ihr bestehende klassische CEs habt, die stabil laufen und keine Wartungsprobleme verursachen → beim klassischen Ansatz bleiben.

In der Praxis decken Content Blocks 70–80 % der typischen Content Elements ab: Teaser, Hero-Banner, Akkordeons, Karten-Grids, Zitat-Blöcke, CTA-Sektionen. Für Listings mit Filterlogik, Formular-Engines oder Shop-Integrationen bleibt Extbase die richtige Wahl.

Bestehende Custom CEs zu Content Blocks migrieren

Die Migration eines klassischen Content Elements zu einem Content Block ist kein automatischer Prozess, aber überschaubar. Folgt diesen Schritten:

1. Felder identifizieren. Öffnet die bestehende TCA-Konfiguration (tt_content.php oder Overrides/tt_content.php) und listet alle Felder auf, die das Element nutzt. Unterscheidet zwischen Custom-Feldern und wiederverwendeten Core-Feldern wie header oder bodytext.

2. config.yaml erstellen. Übersetzt die TCA-Felddefinitionen in die YAML-Syntax. Ein TCA-Feld vom type: input mit eval: trim wird zu type: Text. Ein type: text wird zu type: Textarea. Ein type: file wird zu type: File mit allowed-Array.

3. Fluid-Template portieren. Kopiert das bestehende Fluid-Template. Ersetzt Variablen-Zugriffe: Statt {data.tx_myext_myfield} verwendet ihr {data.my_field} — der Identifier aus der config.yaml ohne Extension-Prefix.

4. Backend-Preview erstellen. Erstellt eine backend-preview.html mit dem Layout Preview und den Sections Header, Content, Footer. Zeigt die wichtigsten Feldwerte als Vorschau.

5. Altes Element entfernen. Entfernt die TCA-Konfiguration, die TypoScript-Registrierung und die Datenbankfelder des alten Elements. Führt ddev typo3 extension:setup aus, damit TYPO3 die neuen Content-Block-Felder anlegt, und leert anschließend den Cache mit ddev typo3 cache:flush. Den vollständigen Workflow für Schema-Updates und Cache-Handling findet ihr in der TYPO3 14 Upgrade-Checkliste.

6. Bestehende Inhalte migrieren. Falls bereits Inhalte mit dem alten CType existieren, müsst ihr den CType in der Datenbank anpassen und die Feldnamen mappen. Das kann per SQL-Migration oder Upgrade Wizard geschehen.

Stolpersteine & Prüfpunkte

Zwei Fehler, die in der Praxis regelmäßig auftreten:

1. YAML-Einrückung und Feldtyp-Fehler

Die config.yaml ist strikt bei der Einrückung. Ein Tab statt Leerzeichen oder eine falsche Verschachtelung führt dazu, dass TYPO3 den Content Block nicht erkennt. Feldtypen sind case-sensitive: Text funktioniert, text nicht. Prüft nach jeder Änderung an der YAML-Datei, ob der Content Block im Backend unter „Neues Inhaltselement" erscheint. Wenn nicht: ddev typo3 cache:flush und die YAML-Syntax validieren.

2. Fehlende labels.xlf-Einträge

Ohne Sprachdatei zeigt TYPO3 die Feld-Identifier als Labels im Backend an — also hero_image statt „Hero-Bild". Das ist funktional korrekt, aber für Redakteure unbrauchbar. Erstellt für jeden Content Block eine language/labels.xlf mit verständlichen Feld-Labels und einer Beschreibung des Elements.

Checkliste: Quick Wins nach dem Einstieg in Content Blocks

  1. Nutzt `useExistingField: true` für `header`, `bodytext` und `image`, statt eigene Felder für Standard-Inhalte anzulegen.
  2. Erstellt ein `icon.svg` für jeden Content Block, damit Redakteure das Element im „Neues Inhaltselement"-Wizard visuell unterscheiden können.
  3. Legt ein Basis-Template für `backend-preview.html` an und kopiert es als Startpunkt für neue Blocks — das spart Zeit und sorgt für konsistente Backend-Vorschauen.
  4. Validiert die `config.yaml` nach jeder Änderung mit einem YAML-Linter (z. B. `yamllint` oder IDE-Plugin), bevor ihr den Cache leert.
  5. Sammelt projektübergreifend verwendbare Content Blocks in einer eigenen Composer-Library, statt sie in jedem Projekt neu zu erstellen.

FAQ — Content Blocks in TYPO3 14

Content Blocks wurden ursprünglich als Extension (`contentblocks/content-blocks`) von der TYPO3 Community entwickelt. Ab TYPO3 13 wurden sie schrittweise in den Core integriert. In TYPO3 14 ist die Content Blocks API Teil des Core-Systems. Für Projekte auf TYPO3 12 und 13 steht die Extension weiterhin als Composer-Package zur Verfügung.

Ja, beide Ansätze koexistieren problemlos. Content Blocks registrieren sich als reguläre CTypes in der `tt_content`-Tabelle. Bestehende Extbase-basierte Content Elements bleiben unverändert funktionsfähig. Ihr könnt neue Elemente als Content Blocks anlegen und bestehende schrittweise migrieren, ohne den laufenden Betrieb zu beeinflussen.

Für die meisten Content Elements genügen fünf Feldtypen: `Text`, `Textarea`, `File`, `Link` und `Collection`. `Collection` ersetzt in der Praxis viele `FlexForm`-Konfigurationen und ist einfacher zu warten. Feldtypen, die einen spezifischen TCA-`renderType` erfordern (z. B. benutzerdefinierte Inline-Widgets), sind über YAML derzeit nicht vollständig abbildbar und erfordern eine manuelle TCA-Erweiterung. Bestehende Core-Felder wie `header` oder `bodytext` werden mit `useExistingField: true` eingebunden, ohne neue Datenbankfelder anzulegen.

Leert zuerst den TYPO3-Cache mit `ddev typo3 cache:flush`. Prüft dann die YAML-Syntax der `config.yaml` auf korrekte Einrückung (Leerzeichen, keine Tabs) und gültige Feldtypen (case-sensitive). Stellt sicher, dass der `name` im Format `vendor/block-name` eindeutig ist und keine Duplikate existieren. Prüft das TYPO3-Log unter `var/log/` auf Fehlermeldungen, die auf ungültige Konfigurationen hinweisen.

Ja, Content Blocks unterstützen die Mehrsprachigkeit von TYPO3 vollständig. Die Feld-Labels und Beschreibungen werden über die `language/labels.xlf` lokalisiert. Die Inhalte selbst nutzen das Standard-Übersetzungskonzept von TYPO3 mit `l10n_parent`-Relationen. Ihr könnt `l10n_mode` pro Feld in der `config.yaml` konfigurieren, um das Übersetzungsverhalten (z. B. „exclude" oder „prefixLangTitle") zu steuern.

Wann lohnt sich externe Unterstützung?

Content Blocks sind bewusst einfach gehalten. Die meisten Integratoren können nach dem ersten Beispiel eigenständig neue Blocks anlegen. Externe Unterstützung wird sinnvoll, wenn einer oder mehrere dieser Punkte zutreffen:

  • Ihr wollt 10+ bestehende Custom Content Elements auf Content Blocks migrieren und der Daten-Migrationsbedarf ist unklar.
  • Euer Projekt nutzt komplexe TCA-Konfigurationen (Paletten, Display Conditions, Inline-Relationen), die nicht 1:1 in YAML übersetzbar sind.
  • Ihr benötigt eine projektübergreifende Content-Block-Library mit einheitlichem Design-System und CI-Pipeline.
  • Euer Team hat bisher ausschließlich mit Extbase gearbeitet und der Paradigmenwechsel erfordert eine gezielte Einführung.

In diesen Fällen könnt ihr Unterstützung bei der Content-Block-Migration anfragen — wir übernehmen die technische Konzeption oder begleiten euer Team beim Einstieg.

Weitere Artikel

Über uns