Was ist weg?
Input-Encoding
Bisher hat Contao Eingaben bereits beim Speichern encodiert, so wurde beispielsweise ein < als < in die Datenbank geschrieben. Ab Contao 6.0 verbleiben alle Daten roh in der Datenbank und werden erst bei der Ausgabe encodiert und maskiert.
Für die tägliche Arbeit im Backend ändert sich dadurch erst einmal nichts. Für die Entwicklung und bei der Ausgabe in den Templates sehr wohl. Ab sofort entscheidet der Kontext, in dem die Daten verarbeitet werden, ob sie 1:1 (raw) ausgegeben werden dürfen oder nicht. Was zum Beispiel in einem HTML-Template als unsicher eingestuft wird, kann bei der Übergabe an eine externe Schnittstelle unproblematisch und sogar gewünscht sein. Gerade bei extern angebundenen Systemen ist es erwünscht, dass Daten roh ankommen und nicht erst mühsam konvertiert werden müssen.
In Twig schützen Encoding (Codierung) und Escaping (Maskierung) die Daten bei der Ausgabe in Templates. Twig nutzt standardmässig UTF-8 und maskiert HTML-Ausgaben, um Cross-Site Scripting (XSS) zu verhindern. Wird aber der Filter |raw verwendet, musst du unbedingt prüfen, welche Daten dort ankommen, denn dort greift der Schutz nicht mehr und es dürfen keine ungeprüften Daten ausgegeben werden. Empfehlenswert ist, raw wo immer es geht zu vermeiden und besser sanitize_html('contao') zu nutzen, damit nur sichere HTML-Tags durchgelassen werden.
Moritz hat das Thema in seinem Vortrag zum Output-Encoding an einem Beispiel wunderbar erklärt. Ausserdem beschreibt Yanick in seinem Rückblick auf das erste Core-Entwicklertreffen 2026 ausführlich, warum Input-Encoding ein Problem ist. Beides lohnt sich zu lesen, wenn du tiefer einsteigen willst.
Contao übernimmt beim Update auf Contao 6.0 die Migration der Datenbank automatisch. Wichtig ist allerdings, dass du von der letzten Contao-5.7-Version aus aktualisierst und dort vorher alle offenen Migrationen durchgeführt hast.
HTML5-Templates
Logische Konsequenz ist nun auch, dass aufgrund der Umstellung auf Output-Encoding die Unterstützung von HTML5-Templates entfällt. Deswegen noch mal ganz deutlich: Das alte Template-System ist vollständig entfernt, Contao 6.0 arbeitet ausschliesslich mit Twig. Alle Templates mit der Endung .html5 funktionieren nicht mehr. Das betrifft nicht nur den Core, sondern auch jegliche Erweiterung.
Das Seitenlayout fe_page wird weiterhin unterstützt. Dazu nutzt du ab sofort die Twig-Version fe_page.html.twig. Der Umstieg auf die neuen Twig-Seitenlayouts mit Slots ist also nicht zwingend, sondern bleibt dir überlassen.
Backend-Themes
Mehrere Backend-Themes sind in Contao 6.0 nicht mehr möglich. Das bisherige Theme «flexible» wird zum Standard und der Ordner system/themes entfällt. Wenn du das Backend individualisieren und anpassen möchtest, dann nutzt du dein angepasstes CSS und fügst dieses über einen Eintrag in der config/config.yaml ein.
# config/config.yaml
contao:
backend:
custom_css:
- files/backend/custom.css
custom_js:
- files/backend/custom.js
In deinem Custom-CSS hinterlegst du zum Beispiel eigene Farben oder ein Logo. Siehe auch docs.contao.org.
BBCode
Das Comments-Bundle unterstützt kein BBCode mehr. Damit konnte man z. B. den Kommentartext formatieren. Bestehende Kommentare migriert Contao beim Update automatisch auf Plaintext, du musst also nichts von Hand nacharbeiten.
Jede Menge alter Code entfällt
Contao 6.0 entfernt im Wesentlichen den Code, der mit der alten HTML5-Template-Engine samt Templates zusammenhängt. So verschwinden über 30.000 Zeilen Altcode aus dem Core. Das zeigt auch, was für einen Koloss das Core-Team da bisher selbst gepflegt hat. Mit Twig setzt Contao jetzt stattdessen auf einen Industriestandard.
Andere Funktionen, die in Contao 5 als «deprecated» markiert sind, bleiben in Contao 6 überwiegend erhalten, sofern sie nicht mit dem Input-Encoding zusammenhängen. Entfernt wird dieser Code erst mit Contao 7. Diese Entscheidung gibt den Entwicklern und Entwicklerinnen von Erweiterungen mehr Zeit für die nötigen Anpassungen.
Was ist anders?
Neben den Dingen, die weggefallen sind, gibt es auch Funktionen, die angepasst oder optimiert wurden.
insert_tag_raw wird zu insert_tag_html
Der Twig-Filter insert_tag_raw heisst jetzt insert_tag_html. Der alte Name funktioniert weiterhin, ist aber deprecated.
Der Filter ist jetzt preescaped, deshalb muss ein raw unbedingt davor kommen. Aus foo|insert_tag_raw|raw wird also foo|raw|insert_tag_html.
Neuer Filehash im DBAFS
Contao berechnet die Datei-Hashes jetzt mit xxh128 statt mit md5. Das ist spürbar schneller, gerade bei grossen Dateibeständen. Für das Update bedeutet das: Synchronisiere das Dateisystem vorher einmal komplett, damit die Migration die Hashes sauber neu aufbauen kann.
File-Insert-Tag mit VFS-Unterstützung
Das Insert-Tag {{file::*}} arbeitet jetzt mit dem virtuellen Dateisystem. Damit greift es auf dieselbe Abstraktionsebene zu wie der Rest von Contao und profitiert von den zusätzlichen Möglichkeiten.
In diesem Zusammenhang wurde das gesamte File-Handling auf das VFS umgebaut. Nutzt du den File-Insert-Tag oder das Download- bzw. Video-Element für eine Datei im files-Verzeichnis, die nicht öffentlich ist, generiert Contao jetzt temporäre URLs zu den geschützten Dateien. Dadurch lassen sich geschützte Dateien für eingeloggte Mitglieder direkt einbinden statt nur als Download anzubieten. Ein Video aus einem geschützten Verzeichnis kannst du damit zum Beispiel jetzt streamen, statt es nur herunterladbar zu machen.
CSS-Klassen für Formularfelder
Eigene CSS-Klassen für Formularfelder setzt Contao jetzt nur noch am umschliessenden Wrapper und nicht mehr zusätzlich an jedem einzelnen Feld darin. Prüfe dein CSS an dieser Stelle, falls du dich bisher auf die Klasse direkt am Feld verlassen hast.
Model-Werte liefern den Default
Fehlt ein Wert, liefert das Model jetzt den Default aus der Spaltendefinition statt null. Ausserdem castet Contao die Werte auf den Spaltentyp der Datenbank. Das sorgt für verlässlichere Rückgabewerte und weniger Sonderbehandlungen im eigenen Code.
Virtuelle Felder
Neben den echten Datenbankfeldern kennt Contao seit Version 5.7 auch virtuelle Felder. Der Hintergrund ist ein praktischer: MySQL begrenzt die Zeilengrösse pro Tabelle. Wer viele Erweiterungen einsetzt, ist bisher an diese Grenze gestossen (Stichwort: «Row size too large») und konnte keine weiteren Felder mehr anlegen. Mit virtuellen Feldern passiert das nicht mehr.
In Contao 6.0 nutzt der Core nun selbst erstmals virtuelle Felder für das Video-Player-Element. Für die Entwicklung bringt der Core ausserdem neu eine AbstractColumnToVirtualMigration mit, die genutzt werden kann, um eigene Felder in virtuelle Felder umzuwandeln.
Wenn du genauer wissen willst, wie virtuelle Felder funktionieren, dann lies dir diesen Beitrag im Handbuch durch: docs.contao.org.
Neue Features
Wie bereits eingangs erwähnt, liegt bei einer Major-Version der Fokus weniger auf neuen Funktionen. Ein paar sind trotzdem dazugekommen.
JSON-LD-Typ bei News
Pro Newsarchiv legst du jetzt fest, welchen JSON-LD-Typ die Beiträge erhalten, zum Beispiel NewsArticle. Die Einstellung findest du in den Experteneinstellungen des Newsarchivs. Zur Verfügung stehen derzeit: NewsArticle, BlogPosting, Article. Damit ordnen Suchmaschinen deine Inhalte präziser ein, was sich positiv auf die Darstellung in den Suchergebnissen auswirken kann.
Primary-Page-Image
In den Seiteneinstellungen kannst du neu ein Seitenbild festlegen. Contao schreibt dieses Bild als primaryImageOfPage in die JSON-LD-Daten der Seite. So bestimmst du selbst, welches Bild Suchmaschinen der Seite zuordnen. Das Bild kann zudem nun auch bei der Contao-Suche genauso wie das Bild der News ausgegeben werden.
Übrigens lässt sich das Bild auch bei Bedarf im Frontend nutzen, etwa als Header-Bild. Dafür erweiterst du dein Twig-Template um die entsprechende Ausgabe. Zugreifen kannst du über contao.page.primaryImage. Damit kannst du dann das Bild im Template generieren:
{% set myimage = figure(contao.page.primaryImage|default, [1200, 500, 'crop']) %}
{% if myimage %}
<div class="primary-image">
{% with {figure: myimage} %}{{ block('figure_component') }}{% endwith %}
</div>
{% endif %}
In Nested-Elements einfügen
Inhaltselemente fügst du jetzt direkt in verschachtelte Elemente ein, ohne vorher die Kindansicht des Elements zu öffnen. So sparst du dir wieder ein paar Klicks im Backend.
Simple-Token-Filter
Mit den neuen Twig-Filtern simple_token und simple_token_html werden Simple-Tokens nun korrekt in Twig-Templates ersetzt. Du kannst Simple-Tokens zum Beispiel beim Newsletter verwenden. Mehr dazu auch im Handbuch.
Abhängigkeiten
Bevor du updatest, wirf noch einen Blick auf die technischen Voraussetzungen von Contao 6.0:
- PHP: 8.4+
- Symfony: 7.4 und 8
- Monolog: 3
- Doctrine DBAL: 4.4+
- Doctrine ORM: 3.6
Das Update auf Contao 6.0
Wenn du jetzt direkt auf Contao 6.0 aktualisieren willst, dann solltest du ein paar wichtige Punkte beachten. Ein paar Hinweise habe ich bereits im Artikel erwähnt, hier noch einmal eine Zusammenfassung dessen, worauf du unbedingt achten musst.
- Update von der letzten Contao 5.7.x aus. Die Migrationen der Datenbank bauen darauf auf. Aktualisiere also zuerst auf die aktuellste 5.7er-Version und wechsle erst danach auf 6.0.
- Vorher
contao:filesyncausführen. Der Filehash wechselt auf xxh128. Unter Contao 5.7 also unbedingt das Dateisystem synchronisieren. Nach dem Update dann direkt noch mal eine Synchronisierung durchführen. - Alle Templates auf Twig umstellen. Die HTML5-Templates funktionieren nach dem Update nicht mehr. Eine Umstellung auf Twig ist also Pflicht. Am besten erledigst du die Arbeit bereits in Ruhe noch unter Contao 5.7.
- Die UPGRADE.md lesen. Sie listet alle Änderungen verbindlich auf und ist bei einer Major-Version Pflichtlektüre.
Wie immer gilt ausserdem: Erstelle vor dem Update ein vollständiges Backup und arbeite am besten in einer Kopie!
Eine vollständige, detaillierte Schritt-für-Schritt-Anleitung für das Update von Contao 5 auf Contao 6 veröffentlichen wir wieder mit der nächsten LTS-Version Contao 6.3.
Soll ich jetzt schon upgraden?
Für die meisten Installationen empfehlen wir, noch zu warten. Besser ist es, zuerst deine Installationen sauber auf Contao 5.7 zu bringen und alle Templates auf Twig umzustellen. Damit erledigst du den grössten Teil der Vorarbeit und bleibst gleichzeitig auf einer LTS-Version mit Support bis 2030.
Dazu kommt: Bisher sind kaum Erweiterungen für Contao 6 freigegeben. Auch die Entwickler und Entwicklerinnen der Erweiterungen müssen ihre Pakete erst an das neue Encoding und an Twig anpassen. Wie immer kannst du mithelfen, indem du ggf. PRs erstellst oder das Ganze finanziell unterstützt.
Weitere Infos
Ebenfalls lesenswert ist auch der offizielle Release-Beitrag auf contao.org und sehenswert ist das YouTube-Video der Contao Academy.
trakked ist kompatibel mit Contao 6.0
Wie gewohnt stehen dir bei trakked alle bekannten Funktionen auch für Contao 6.0 zur Verfügung.
Changelog der behobenen Fehler in Contao 6.0.0:
-
#10144
Unterstützung von
allowHtmlnur für das Feldcaptionim Meta-Assistenten ( zoglo ) - #10152 JSON-Werte bei der Migration der Ausgabekodierung überspringen ( ausi )
- #10148 Überflüssige Entitätsdekodierung entfernen ( Toflar )
-
#10143
Verwendung des veralteten
$strTagEndingentfernen ( ausi ) - #10141 Doppelt kodierte Werte im Kalender- und Nachrichten-Bundle beheben ( zoglo )
-
#10133
Das Feld
backendWidthin die Backend-Einstellungen verschieben ( zoglo ) - #10114 Den Seitentitel und die Beschreibung nicht doppelt kodieren ( ausi )
-
#10099
Input::get()für dynamische URL-Parameter wieauto_itemnicht als veraltet kennzeichnen ( ausi ) - #10096 Die vorhandenen Schließen- und Chevron-Symbole in den Formular-Stylesheets verwenden ( leofeyer )
-
#10098
Den Konflikt zwischen
doctrine/ormundsymfony/doctrine-bridgebeheben ( ausi )
Changelog der behobenen Fehler in Contao 6.0.0-RC2:
-
#10092
Die verbleibenden
|insert_tag_rawdurch|insert_tag_htmlersetzen ( leofeyer ) - #10087 Das «richtige» TinyMCE-Paket verwenden ( leofeyer )
- #10085 Auf ALTCHA v3 aktualisieren ( leofeyer )
- #10082 Eine Mindeststrichbreite für SVG-Symbole sicherstellen ( leofeyer )
-
#10056
insert_tag_rawzur DateiUPGRADE.mdhinzufügen ( ausi ) -
#10069
Den Seitennamen im
HtmlHeadBagspeichern und im Breadcrumbs-Modul verwenden ( ausi ) -
#10066
Die Größe von
tl_log.browsererhöhen ( ausi ) - #10042 Eine höhere Priorität für die Migration der Ausgabekodierung verwenden ( zoglo )
-
#10041
Verwendung einer Twig-Vorlage für die Einfüge-Tags
{{news::*}},{{event::*}}und{{faq::*}}( ausi ) -
#10038
Die veraltete Methode
HtmlDecoder::inputEncodedToPlainText()als veraltet kennzeichnen ( ausi ) -
#10037
Den Twig-Filter
insert_tag_rawininsert_tag_htmlumbenennen ( ausi ) -
#10035
ChunkedTextentfernen und stattdesseninsert_tag_rawvorab escapen ( ausi ) -
#10032
Die Berechtigungsprüfung für die Operation
pasteintokorrigieren ( lukasbableck ) - #10034 Die Ausgabekodierung bei Einfüge-Tags, Newslettern und Vorlagen korrigieren ( ausi )
Changelog der neuen Funktionen in Contao 6.0.0-RC1:
- #10018 Eine wiederverwendbare Migration «column to virtual» hinzufügen ( leofeyer )
- #9584 Die Benutzererfahrung des Tooltip-Controllers verbessern ( zoglo )
- #10013 Die Standardwerte aus dem Schema in den Modellen zurückgeben ( ausi )
-
#9999
ARIA-Labels hinzufügen, wo kein
<label>-Element vorhanden ist ( leofeyer ) - #9983 Symfony 8 zulassen ( Toflar )
-
#10001
Die veralteten
Backend.Theme-Skripte entfernen, für die es bereits Stimulus-Alternativen gibt ( zoglo ) - #9992 Einen einfachen Token-Filter für Twig hinzufügen ( ausi )
-
#8349
Eine «Einfügen in»-Funktion zur übergeordneten Ansicht
DC_Tablehinzufügen ( lukasbableck ) - #9548 Die veralteten Migrationen aus den Stimulus-Controllern entfernen ( zoglo )
- #9540 Die Veraltungshinweise aus dem Kalender-Bundle entfernen ( zoglo )
- #9981 Benutzerdefinierte Formularfeldklassen nur zum äußeren Container hinzufügen ( leofeyer )
- #9565 Das Hinzufügen eines Hauptbildes zu einer Seite ermöglichen und dieses im JSON-LD verwenden ( lukasbableck )
- #9962 Den veralteten Callback für untergeordnete Datensätze entfernen ( ausi )
-
#9944
Input::get('language')als veraltet kennzeichnen ( ausi ) - #9947 Veraltete Widget-Attribute entfernen ( ausi )
- #9557 Die Migration für die Ausgabekodierung hinzufügen ( ausi )
- #9576 Option zum Ändern des JSON-LD-Typs für Nachrichten hinzufügen ( lukasbableck )
- #9946 Basic-Entitäten für Nicht-HTML-Felder in Unicode konvertieren ( ausi )
-
#9945
Verwendungen von
Input::setPost()entfernen ( ausi ) -
#9943
Input::setGet()ausDC_Tableentfernen ( ausi ) -
#9942
Die meisten Methoden der Klasse
Inputals veraltet kennzeichnen ( ausi ) -
#9930
Ländercodes nicht in
tl_member.languageaufnehmen ( ausi ) -
#9941
Input::setGet()im Suchmodul nicht verwenden ( ausi ) - #9938 Doppelte Kodierung aktivieren ( ausi )
-
#7430
Weitere
$GLOBALS['objPage']durch den Seitenfinder-Dienst ersetzen ( leofeyer ) -
#7014
$GLOBALS['objPage']durch den Seitenfinder ersetzen ( leofeyer ) -
#9582
Die Datei
manifest.jsonin der MethodeImage::getHtml()verwenden ( zoglo ) -
#9534
Die Vererbung von
Module,ContentElementundHybridals veraltet markieren ( Toflar ) - #9541 Die Verweise auf veraltete Funktionen aus dem Kommentar-Bundle entfernen ( zoglo )
- #9542 Die Verweise auf veraltete Funktionen aus dem FAQ-Bundle entfernen ( zoglo )
- #9543 Die Verweise auf veraltete Funktionen aus dem Manager-Bundle entfernen ( zoglo )
- #9544 Die Verweise auf veraltete Funktionen aus dem News-Bundle entfernen ( zoglo )
- #9545 Die Verweise auf veraltete Funktionen aus dem Newsletter-Bundle entfernen ( zoglo )
-
#9572
Die veraltete Unterstützung für
customSchemaOptionsentfernen ( fritzmg ) -
#9577
Implementierung eines korrekten Einfüge-Tags
{{file::*}}auf Basis des VFS ( Toflar ) -
#9551
Umbenennung des Namensraums für Benutzervorlagen in
@Contao_User( m-vo ) -
#9536
Den veralteten
FilterPageTypeEvent-Dienst entfernen ( Toflar ) -
#9599
var/logsinvar/logumbenennen ( leofeyer ) - #9566 Die Symfony-Bundle-Vorlagen entfernen ( m-vo )
- #9546 Die Bundle-Migrationen entfernen ( zoglo )
- #9556 Unterstützung für Swift Mailer entfernen ( bytehead )
-
#9558
Unterstützung für
doctrine/dbalv3 entfernen ( Toflar ) -
#9535
Den veralteten
EntityCacheTags-Dienst entfernen ( Toflar ) - #9533 Funktionalität zur Verarbeitung öffentlicher URIs im VFS zum Player hinzufügen ( fritzmg )
- #9498 Die Verarbeitung öffentlicher Dateien im VFS überarbeiten ( Toflar )
-
#9524
RenderPageEvententfernen ( Toflar ) -
#9505
Eingabekodierung in der
Widget-Klasse entfernen ( ausi ) -
#9485
Das
flexible-Theme in die Build-Kette verschieben ( zoglo ) - #9484 Das veraltete Vorlagensystem entfernen ( m-vo )
- #9332 PHP-native Lazy-Objekte verwenden ( fritzmg )
- #9414 Alle SQL-Definitionen auf Array-Notation umstellen ( fritzmg )
- #9482 Zusammenführung veralteter Header entfernen ( Toflar )
- #9480 Das globale Request-Token für Vorlagen entfernen ( aschempp )
- #9483 Die veralteten Schnittstellen für die Nachrichtenpriorität entfernen ( Toflar )
- #9479 Unterstützung für Service-Annotationen entfernen ( aschempp )
Changelog der behobenen Fehler in Contao 6.0.0-RC1:
-
#10030
Die verbleibenden Verwendungen von
Inputersetzen ( ausi ) - #10029 Benutzereigenschaften im Backend-Kopfmenü kodieren ( ausi )
-
#10027
Die Dateien
DEPRECATED.mdundUPGRADE.mdaktualisieren ( leofeyer ) - #10023 Die veralteten Doctrine-DBAL-Methoden nicht mehr verwenden ( leofeyer )
-
#10022
Die Methode
generate()aus den Frontend-Formular-Widgets entfernen ( ausi ) - #10020 Weitere Ausgabekodierungen hinzufügen ( ausi )
-
#10021
Nicht verwendete
Backend-Methoden entfernen ( ausi ) -
#10019
Für nicht-null-Spalten in Modellen nicht
nullzurückgeben ( ausi ) -
#10006
Die Klasse
Inputaus demDcaUrlAnalyzer, den Operationen, dem Paletten-Builder und mehreren Listenern entfernen ( ausi ) - #9997 URLs in Kommentaren automatisch verlinken und als Klartext darstellen ( ausi )
- #9977 «Contao 6» in den Veraltungshinweisen durch «Contao 7» ersetzen ( leofeyer )
- #9988 Seit Contao 4 veraltete Konfigurationsknoten entfernen ( leofeyer )
-
#9989
Das aktive Breadcrumb-Element in
<strong>-Tags einfügen ( leofeyer ) - #9994 BBCode entfernen ( ausi )
- #9990 Auf einen neueren DBAFS-Hash-Algorithmus umstellen ( m-vo )
- #9986 Das Ändern des Passworts im Modul «Persönliche Daten» verhindern ( leofeyer )
-
#9987
$strIpin Benutzerklassen als veraltet kennzeichnen ( fritzmg ) -
#9980
Die XML-Datei mit den Formulardaten mithilfe von
DOMDocumentgenerieren ( leofeyer ) -
#9979
Setter aus der Klasse
RecordLabelentfernen ( ausi ) - #9969 Widgets und Optionen kodieren und bereinigen ( ausi )
-
#9966
Ein
RecordLabel-Objekt für den Label-Callback hinzufügen ( ausi ) - #9974 Sicherstellen, dass «&»-Zeichen in URLs korrekt kodiert werden ( leofeyer )
- #9968 «&»-Zeichen in der URL der Zurück-Schaltfläche nicht kodieren ( leofeyer )
-
#9965
findById()anstelle vongetRelated()verwenden ( leofeyer ) - #9967 Labels im «Show»-Modal kodieren ( ausi )
- #9963 Die Gruppenüberschrift in der übergeordneten Ansicht kodieren ( ausi )
- #9952 Das Inhaltslabel korrekt kodieren ( ausi )
- #9954 Labels von Mitgliedergruppen ordnungsgemäss kodieren ( ausi )
-
#9892
Das fehlende
$objPageinFrontendTemplate::setCacheHeadersbeheben ( aschempp ) - #9628 Beim Rendern von Twig-Komponenten eine Delegate-Vorlage verwenden ( m-vo )
-
#9578
Die Standardvorlage von
FigureRendererkorrigieren ( m-vo ) -
#9568
Alle Verwendungen von
StringUtil::ampersand()entfernen ( m-vo ) - #9506 Den Response-Kontext zur Generierung des Nonce verwenden ( bytehead )
- #9497 Die Mindestversion für Doctrine ORM erhöhen ( fritzmg )
Über Contao 6.0
Die erste stabile Version von Contao 6.0 wurde am 26. August 2026 veröffentlicht und wird der Nachfolger von Contao 5.7. Die 6.0 wird bis am 14. Februar 2027 mit Updates versehen und wird danach von Contao 6.1 abgelöst.