pdir / contao-block-editor-bundle
Fast, block-based visual editor for Contao – edit content elements inline, directly in the frontend preview.
Package info
github.com/pdir/contao-block-editor-bundle
Language:TypeScript
Type:contao-bundle
pkg:composer/pdir/contao-block-editor-bundle
Requires
- php: ^8.3
- contao/core-bundle: ^5.7 || ^6.0
- doctrine/dbal: ^3.7 || ^4.3
- symfony/config: ^7.4 || ^8.0
- symfony/dependency-injection: ^7.4 || ^8.0
- symfony/event-dispatcher: ^7.4 || ^8.0
- symfony/http-foundation: ^7.4 || ^8.0
- symfony/http-kernel: ^7.4 || ^8.0
- symfony/routing: ^7.4 || ^8.0
- symfony/security-bundle: ^7.4 || ^8.0
- symfony/security-core: ^7.4 || ^8.0
- symfony/security-csrf: ^7.4 || ^8.0
- twig/twig: ^3.21
Requires (Dev)
- contao/manager-plugin: ^2.0
- phpunit/phpunit: ^11.5 || ^12.0
Suggests
None
Provides
None
Conflicts
- contao/manager-plugin: <2.0 || >=3.0
Replaces
None
This package is auto-updated.
Last update: 2026-11-08 16:38:05 UTC
README
Contao Block Editor ist ein moderner, performanter Editor für Contao, inspiriert von blockbasierten Editoren wie Gutenberg, aber gebaut für die Contao-Architektur. Redakteure klicken ein Element in der Live-Vorschau an und bearbeiten es sofort, ohne Ladezeiten, Seitenwechsel oder Umweg über das Backend-Formular. Alle Inhalte bleiben ganz normale Contao-Inhaltselemente: Templates, Insert-Tags, Versionierung, Benutzerrechte und Elemente anderer Erweiterungen funktionieren wie gewohnt.
block-editor-demo.mp4
Klick auf das Bild öffnet das Video (1 Minute).
Highlights
- Inline-Bearbeitung direkt im Frontend-Rendering
- Sofortiger Wechsel vom Klick zum Editieren, ohne Server-Roundtrip
- Drag & Drop, Undo/Redo und Autosave
- Inspector automatisch aus dem DCA generiert, auch für Drittanbieter-Elemente
- Respektiert Contao-Benutzerrechte und Versionierung
- Jederzeit Rückfall auf das klassische Backend
Stand
Umgesetzt sind Inline-Text (Elemente text und headline), Inspector aus dem DCA, Autosave mit Versionierung und das
Verschieben von Elementen, auch zwischen Artikeln und Spalten: per Griff links neben dem Element oder mit Alt + Pfeil
hoch/runter, wenn das Element den Fokus hat. Ziel ist immer ein bearbeitbares Element, leere Artikel sind noch kein
Ablageziel. Links außerhalb der bearbeitbaren Elemente führen im Editor zur nächsten Seite, vorher wird alles gespeichert;
externe Links und Dateien öffnen einen neuen Tab. Links im Inhalt zeigen beim Klick eine Leiste mit Öffnen und Bearbeiten;
im Text lassen sie sich dort ändern oder entfernen und mit Strg/Cmd + K neu anlegen. Liegt ein Element in einem
anderen, etwa in einer Gruppe oder einem Modul, wählt der erste Button der Leiste über dem Text das übergeordnete Element aus. Der Editor öffnet sich im Backend über die Operation „Im Block-Editor öffnen“ im Seitenbaum.
Unter „Mehr erfahren“ im Inspector lässt sich „Navigationslinks bearbeiten“ einschalten: Ein Klick auf einen Menüpunkt
ändert dann den Seitennamen direkt im Menü, und der Inspector zeigt die weiteren Angaben der Seite. Es gelten die Rechte
für Seiten aus dem Backend, gespeichert wird mit Versionierung wie bei den Elementen.
Auf der Detailseite einer Nachricht oder eines Events lassen sich der Titel (bei Nachrichten auch die Unterüberschrift)
direkt in der Seite und im Inspector ändern, mit den Rechten und der Versionierung des Backends. In Nachrichtenlisten
gilt das für Titel und Teaser jedes Beitrags; ein Teaser aus einem einzigen Absatz wird direkt in der Liste bearbeitet,
längere mit Formatierung im Inspector. Ist kein Element
ausgewählt, zeigt der Inspector Seitentitel und Beschreibung der aktuellen Seite für Suchmaschinen; sie werden ebenso
gespeichert.
Neue Elemente kommen über das Plus unter dem Griff oder den Button „Element darunter einfügen“ im Inspector unter das
gewählte Element. Zur Wahl stehen die Elementtypen, die der Benutzer an dieser Stelle anlegen darf, auch in verschachtelten
Elementen; das neue Element erhält die Standardwerte aus dem DCA und öffnet sich gleich zum Schreiben.
Ein Artikel ohne Elemente zeigt im Editor eine Fläche „Element einfügen“ für das erste Element.
Tabellen werden Zelle für Zelle in der Seite bearbeitet: Tab springt zur nächsten Zelle, die Leiste über der Tabelle
fügt Zeilen und Spalten ein oder löscht sie. Zellen mit HTML und alle Zellen per Tastatur bearbeitet der Inspector.
Aufzählungen ebenso Eintrag für Eintrag: Enter legt darunter einen neuen Eintrag an, Rücktaste in einem leeren Eintrag
entfernt ihn. Einträge mit HTML bearbeitet der Inspector.
Ein Klick auf ein Bild bietet an, es auszutauschen: Es öffnet sich der Dateiwähler von Contao mit den Dateitypen, die
das Feld erlaubt. Im Inspector stehen die Dateien eines Elements mit Vorschau, bei Galerien in ihrer Reihenfolge, dazu die
Bildgröße.
Beschreibungslisten wie Kennzahlen oder Zeitleisten lassen sich Begriff für Begriff in der Seite bearbeiten: Enter springt vom
Begriff zur Beschreibung und weiter zu einem neuen Eintrag.
Mehrzeilige Textfelder ohne Editor, etwa der Badge-Text im Hero, werden ebenfalls in der Seite bearbeitet:
Umschalt + Enter beginnt eine neue Zeile, Enter beendet die Eingabe. Danach zeigt das Template die Zeilen wieder an.
Datumsfelder wie „Anzeigen ab/bis“ nutzen die Datumsauswahl des Browsers. Felder, die Contao in einer gemeinsamen
JSON-Spalte speichert (z. B. „Serverseitiger Seitenumbruch“ der Galerie), bearbeitet der Inspector wie andere Felder.
Felder, die andere Bundles erst beim Bearbeiten in die Paletten aufnehmen (ihre onload_callback), erscheinen
ebenfalls, etwa „Erweiterte CSS-Klassen“. Die „CSS-Stil Auswahl“ des CSS Style Selector zeigt je Stilgruppe eine Auswahl.
„Löschen“ im Inspector entfernt das gewählte Element samt verschachtelter Elemente, wenn der Benutzer es löschen darf.
Dasselbe geht direkt am Element: mit dem Papierkorb zwischen Griff und Plus, beim Bearbeiten eines Textes mit dem
Papierkorb in der Leiste darüber oder mit Entf bzw. ⌫, wenn das Element selbst den Fokus hat.
Wie im Backend landet es in „Wiederherstellen“; direkt danach holt „Rückgängig“ in der Kopfzeile es zurück.
Mit dem Stift in der Kopfzeile oder der Taste E lässt sich das Bearbeiten ausschalten, um sich nur auf der Seite zu
bewegen: Dann führt jeder Link zu seiner Seite. Jeder neue Editor startet mit eingeschaltetem Bearbeiten.
Die Tastaturbefehle erklärt der Inspector unter „Globale Tastaturbefehle“ (Taste ?). Einzelne Tasten wirken nur,
wenn gerade kein Text bearbeitet wird, und lassen sich für Screenreader abschalten. Beim Schreiben gilt nur
Strg/⌘ + Umschalt + Komma für den Inspector. Kombinationen der Browser und Tasten, die Zeichen erzeugen (⌥ auf dem Mac,
AltGr unter Windows), bleiben unberührt.
Noch offen: Kopieren, globales Undo/Redo, Patterns, Sprachwechsel, Responsive-Vorschau und die Erweiterungs-API. Felder, die der Editor noch nicht unterstützt, bleiben über den Link „Im klassischen Backend bearbeiten“ erreichbar.
Installation
Voraussetzung ist Contao 5.7 oder 6.0 mit PHP 8.3 oder neuer (Contao 6 verlangt PHP 8.4).
Contao Managed Edition
Es sind keine manuellen Schritte nötig. Das Bundle und seine Routen werden über das Manager-Plugin registriert:
composer require pdir/contao-block-editor-bundle
Contao als Teil einer eigenen Symfony-Anwendung
Ohne Managed Edition wird das Manager-Plugin nicht ausgeführt. Voraussetzung ist eine bereits lauffähige Contao-Installation; danach sind diese Schritte manuell nötig:
1. Paket installieren
composer require pdir/contao-block-editor-bundle
2. Bundle registrieren in config/bundles.php, nach dem ContaoCoreBundle:
return [ // ... Contao\CoreBundle\ContaoCoreBundle::class => ['all' => true], Pdir\ContaoBlockEditorBundle\ContaoBlockEditorBundle::class => ['all' => true], ];
3. Routen einbinden in config/routes.yaml, vor den Contao-Routen:
pdir_block_editor: resource: '@ContaoBlockEditorBundle/config/routes.yaml' contao: resource: '@ContaoCoreBundle/config/routes.yaml'
4. Vorschau-Einstieg einrichten. Der Editor zeigt die Seite über das Vorschau-Skript von Contao an. Die Managed Edition
bringt es mit, sonst ist contao.preview_script leer und der Editor meldet, dass das Skript fehlt.
In config/packages/contao.yaml:
contao: preview_script: /preview.php
Dazu die Datei public/preview.php anlegen und bei Bedarf an den eigenen Front-Controller anpassen:
<?php declare(strict_types=1); use App\Kernel; use Symfony\Component\HttpFoundation\Request; require dirname(__DIR__).'/vendor/autoload.php'; $request = Request::createFromGlobals(); $request->attributes->set('_preview', true); $kernel = new Kernel('prod', false); $response = $kernel->handle($request); $response->headers->set('X-Robots-Tag', 'noindex'); $response->headers->set('Cache-Control', 'no-store'); $response->send(); $kernel->terminate($request, $response);
Diese Datei darf nicht über einen HTTP-Cache wie HttpCache laufen, sonst könnten Vorschauseiten mit Editor-Markup
im Cache landen. Der Webserver muss sie außerdem als PHP-Skript ausführen, auch mit Pfadanteil (/preview.php/seite.html).
5. Assets veröffentlichen und Cache leeren
bin/console assets:install public bin/console cache:clear
Eine Datenbank-Migration ist nicht nötig, weil das Bundle keine eigenen Tabellen oder Spalten anlegt.
Update
Nach jedem Update müssen die Dateien unter public/bundles/contaoblockeditor zur Bundle-Version passen. In der Managed
Edition erledigt das contao-setup bei composer install und composer update. Sonst und bei Entwicklung per
Path-Repository:
bin/console assets:install public --symlink
Mit --symlink bleiben die Dateien automatisch aktuell. Passen sie nicht zusammen, öffnet sich der Editor nicht und
zeigt diesen Hinweis, denn alte Skripte verstehen die aktuelle API nicht und könnten Inhalte beschädigen.
Den Editor für formatierten Text erweitern
Felder mit WYSIWYG-Editor im Backend (eval.rte) bearbeitet der Block-Editor in der Seite und im Inspector mit einem
schlanken Editor (Tiptap): Fett, Kursiv, Link sowie Aufzählungen. Andere Bundles können weitere
Formate und Buttons ergänzen. Dazu tragen sie ein Skript ein, das im Block-Editor und in der Seitenvorschau geladen wird:
# config/config.yaml contao_block_editor: editor_scripts: - bundles/acmeeditor/block-editor.js
Das Skript legt seine Erweiterung in window.contaoBlockEditorExtensions ab. Die Reihenfolge der Skripte spielt keine
Rolle, weil der Editor die Liste erst beim Start liest:
(window.contaoBlockEditorExtensions ??= []).push({ // Tiptap-Erweiterungen, gebaut mit den Klassen des Editors (Extension, Mark, Node, mergeAttributes) extensions: ({ Mark }) => [ Mark.create({ name: 'superscript', parseHTML: () => [{ tag: 'sup' }], renderHTML: () => ['sup', 0], }), ], // Buttons in der Formatleiste buttons: [{ label: 'x²', title: 'Hochgestellt', // Optional: Pfad eines 24 × 24 großen Icons wie die von Contao, sonst steht das Label auf dem Button icon: { d: 'M4 18 9 6h2l5 12h-2l-1.3-3.3H7.3L6 18Zm4-5h4L10 8Z', rule: 'nonzero' }, run: (editor) => editor.chain().focus().toggleMark('superscript').run(), active: (editor) => editor.isActive('superscript'), }], // Markup, das die Erweiterung schreibt: Texte damit bleiben im Editor bearbeitbar allow: { SUP: [] }, });
Texte mit Markup, das weder der Editor noch eine Erweiterung kennt, öffnet der Block-Editor nur als HTML, damit nichts verloren geht. Was gespeichert wird, filtert Contao weiterhin nach den erlaubten Tags aus den Einstellungen.
Lizenz
Der Block-Editor steht unter der GNU Lesser General Public License, Version 3 oder (nach Wahl) jeder späteren
Version (LGPL-3.0-or-later). Den Lizenztext enthält LICENSE.
Die Icons der Formatleiste stammen aus dem Standard-Iconset von HugeRTE, dem
Editor für formatierten Text im Contao-Backend. Sie stehen unter der MIT-Lizenz, © 2022 Ephox Corporation DBA Tiny
Technologies, Inc. und © 2025 HugeRTE contributors. Den Lizenztext enthält
licenses/HugeRTE.txt.
Entwicklung
composer install npm ci --ignore-scripts && npm rebuild esbuild npm run build # erzeugt public/ und prüft das Größenbudget npm run typecheck npm test vendor/bin/phpunit
Die Browser-Tests in tests/e2e/ laufen gegen eine echte Contao-Instanz mit den Daten aus tests/e2e/seed.sql
(Test-Zugänge, nur lokal verwenden). Das Skript erwartet die Instanz unter http://127.0.0.1:8765 und playwright
als Abhängigkeit. Der Lauf ändert die Testdaten, daher vor jedem Lauf die Elemente 10 und 11 zurücksetzen.