SEO & Technik

Content Blocks in TYPO3 14 — Custom Content Elements ohne PHP-Boilerplate

Ein eigenes Inhaltselement in TYPO3 klassisch anzulegen bedeutete bisher: TCA-Definition, Registrierung in ext_localconf.php, TypoScript fürs Rendering, Fluid-Template, Backend-Vorschau, Sprachdatei — sechs bis acht Dateien, bei jedem Element aufs Neue, mit viel Copy-Paste und entsprechendem Fehlerpotenzial. Content Blocks ersetzen das durch eine config.yaml und ein Template. Dieser Artikel zeigt den Aufbau, die Feldtypen, die in der Praxis tatsächlich zählen, und die Stelle, an der Content Blocks aufhören und ein Extbase-Plugin anfängt. Für Integratoren und Entwickler, die regelmäßig eigene Inhaltselemente bauen.

26.02.2026 · Patrick Schatzschneider · 4 Min. Lesezeit
Hände stecken zwei modulare Bausteine über einem Schreibtisch zusammen, ein Baustein violett
Content Block

Ein Content Block ist ein deklarativ definierter Inhaltstyp in TYPO3. Felder werden in einer config.yaml beschrieben, die Ausgabe in einem Fluid-Template; TYPO3 erzeugt daraus TCA und Datenbankfelder selbst und registriert den CType automatisch.

Abgrenzung

Im klassischen Ansatz schreiben Sie TCA und TypoScript von Hand und registrieren das Element manuell. Content Blocks nehmen Ihnen diesen Teil ab — um den Preis, dass sehr spezielle TCA-Konstruktionen nicht abbildbar sind.

Der Aufbau eines Content Blocks

Jeder Block ist ein Verzeichnis mit fester Struktur — in unserem Projekt liegen sie unter packages/cb/ContentBlocks/ContentElements/:

  • config.yaml — Name und Felder
  • templates/frontend.html — die Ausgabe
  • templates/backend-preview.html — die Vorschau im Seitenmodul
  • language/labels.xlf — Feldbeschriftungen
  • assets/icon.svg — das Symbol im Auswahldialog

Verbindlich sind davon nur die ersten beiden. Die übrigen drei entscheiden darüber, ob Redakteure mit dem Element arbeiten können oder daran scheitern — dazu unten mehr.

Der name folgt dem Format vendor/block-name und muss projektweit eindeutig sein. Aus ihm leitet TYPO3 den CType ab: Aus vibe/hero-banner wird cb_hero_banner.

Die fünf Feldtypen, die Sie wirklich brauchen

Content Blocks kennen ein gutes Dutzend Feldtypen. In der Praxis decken fünf davon fast alles ab:

Text und Textarea für Beschriftungen und kurze Texte — mit max begrenzen, sonst entstehen Layouts, die im Entwurf gut aussahen.

File für Bilder und Dokumente, mit maxitems und erlaubten Typen.

Link für Verweise, mit allowedTypes auf das eingrenzen, was sinnvoll ist (page, url, email).

Collection für wiederholbare Gruppen — Listenpunkte, Karten, Akkordeon-Einträge. Dieser Typ ersetzt in der Praxis die meisten früheren FlexForm-Konstruktionen und ist erheblich wartungsfreundlicher.

useExistingField: true ist streng genommen kein Feldtyp, aber der wichtigste Schalter: Er bindet vorhandene Core-Felder wie header oder bodytext ein, statt neue Datenbankspalten anzulegen.

Das Frontend-Template

frontend.html ist ein gewöhnliches Fluid-Template. Alle in der config.yaml definierten Felder stehen über {data} bereit, benannt nach ihrem identifier.

Wichtig ist die Behandlung optionaler Felder: Jedes Feld, das leer bleiben darf, gehört in eine f:if-Bedingung — und zwar so, dass bei leerem Feld kein Wrapper-Markup übrig bleibt. Sonst erzeugen leere Felder sichtbare Abstände, die niemand zuordnen kann.

Die drei Dateien, die man sich spart — und dann nachbaut

Backend-Vorschau, Sprachdatei und Icon sind technisch optional. Fehlen sie, passiert Folgendes:

Ohne labels.xlf zeigt das Backend die Feld-Identifier als Beschriftung — also hero_image statt „Hintergrundbild". Funktional korrekt, für Redakteure unbrauchbar.

Ohne backend-preview.html sieht man im Seitenmodul nur den CType-Namen. Bei einer Seite mit fünfzehn Elementen ist nicht mehr erkennbar, welches welches ist.

Ohne icon.svg sind alle Elemente im Auswahldialog visuell identisch.

Jede dieser drei Dateien kostet Minuten. Sie nachträglich für 47 Blocks zu ergänzen, kostet einen Tag — deshalb gehören sie ins Basis-Template, aus dem neue Blocks entstehen.

Wo Content Blocks aufhören

Content Blocks sind für feldbasierte Inhaltselemente gebaut. Für alles darüber hinaus bleibt Extbase die richtige Wahl:

  • Das Element braucht nur Felder und ein Template → Content Block
  • Es braucht eine eigene Tabelle mit Repository-Abfragen oder echte Geschäftslogik → Extbase-Plugin
  • Es lädt Daten aus externen Quellen oder rechnet aufwendig → Extbase-Plugin oder ein DataProcessor
  • Es braucht einen speziellen TCA-renderType oder verschachtelte Inline-Beziehungen → klassisches TCA, mindestens ergänzend

Beide Ansätze funktionieren nebeneinander. Content Blocks registrieren sich als reguläre CTypes in tt_content; bestehende Extbase-Elemente bleiben unberührt. Sie können also neue Elemente als Content Blocks anlegen und Altes schrittweise überführen, ohne den Betrieb anzufassen.

Extbase-Plugin

Ein Extbase-Plugin ist ein Erweiterungstyp mit vollständigem MVC-Aufbau aus Domain-Modell, Repository und Controller. Es kapselt Geschäftslogik, eigene Tabellen und externe Datenquellen.

Abgrenzung

Im Gegensatz zu Content Blocks erfordert es PHP-Code und lohnt sich nicht für einfache, feldbasierte Elemente — dort erzeugt es genau den Boilerplate, den Content Blocks abschaffen.

Quick Wins für den Einstieg

  1. `useExistingField: true` für header, bodytext und image nutzen statt eigener Felder
  2. Neue Textfelder auf Element-Ebene als Textarea anlegen — sie zählen nicht gegen die Zeilengrenze von tt_content
  3. Basis-Template mit config.yaml, beiden Fluid-Dateien, labels.xlf und icon.svg anlegen und als Startpunkt kopieren
  4. Optionale Felder im Template so kapseln, dass bei leerem Feld kein Wrapper-Markup entsteht
  5. Bei Link-Feldern auf `.url` prüfen, nicht auf das Feld selbst
  6. YAML nach jeder Änderung validieren, bevor der Cache geleert wird
  7. Neuen CType in der keepItems-Whitelist der TSconfig freigeben
  8. Projektübergreifend nutzbare Blocks in ein eigenes Composer-Paket auslagern statt sie zu kopieren

Häufig gestellte Fragen

Beides, je nach Version. Ursprünglich als Community-Extension entwickelt, wurden sie ab TYPO3 13 schrittweise in den Core übernommen; in TYPO3 14 ist die API Teil des Cores. Für Projekte auf v12 und v13 gibt es die Extension weiterhin als Composer-Paket.

Ja, problemlos. Content Blocks registrieren sich als normale CTypes in tt_content, bestehende Extbase-Elemente laufen unverändert weiter. Eine Migration lässt sich elementweise durchführen, ohne den Betrieb zu unterbrechen.

In den meisten Fällen fehlt die Freigabe des CTypes in der keepItems-Liste der Seiten-TSconfig — die Konfiguration ist dann korrekt, das Element aber nicht auswählbar. Sonst: Cache leeren, YAML-Einrückung prüfen (Leerzeichen statt Tabs), Feldtypen auf Schreibweise kontrollieren, name auf Eindeutigkeit prüfen und ins Log sehen.

Vollständig. Beschriftungen werden über language/labels.xlf lokalisiert, die Inhalte folgen dem normalen Übersetzungskonzept mit l10n_parent. Das Übersetzungsverhalten einzelner Felder steuern Sie über l10n_mode in der config.yaml.

Ja, aber es ist Handarbeit. Die Felddefinition schreiben Sie in YAML neu, das Fluid-Template lässt sich meist übernehmen. Aufwendig wird es, wenn Feldnamen sich ändern — dann müssen bestehende Datensätze mitgezogen werden. Planen Sie diesen Schritt als eigene Aufgabe, nicht als Nebenprodukt.

Wann sich Unterstützung lohnt

Content Blocks sind bewusst einfach. Die meisten Integratoren legen nach dem ersten Beispiel eigenständig neue Elemente an. Sinnvoll wird Hilfe, wenn:

  • zehn oder mehr bestehende Elemente migriert werden sollen und der Datenbedarf unklar ist
  • komplexe TCA-Konstruktionen im Spiel sind, die sich nicht eins zu eins in YAML abbilden lassen
  • eine projektübergreifende Block-Bibliothek mit einheitlichem Design-System entstehen soll
  • Ihr Team bislang ausschließlich mit Extbase gearbeitet hat

Nächster Schritt

Content Blocks im eigenen Projekt einführen? Wir haben 47 davon gebaut.

Wir konzipieren die Struktur, migrieren bestehende Elemente oder begleiten Ihr Team beim Einstieg — je nachdem, was Sie brauchen.

Lieber anrufen? 09075 5923957 Mo–Fr, 8–18 Uhr

Patrick Schatzschneider Patrick Schatzschneider Geschäftsführer
Der Aufwand steckt nicht im ersten Block, sondern in der Struktur für die nächsten vierzig.

Vibe Digital GmbH · gegründet 2020 · Raum Ulm

  1. Sie schreiben mit TYPO3-Version und Anzahl eigener Elemente
  2. Wir antworten in unter 3 Stunden ein Mensch, kein Ticketsystem
  3. 30 Minuten Gespräch mit Einschätzung zum Migrationsaufwand
Über uns