Twig 4.0 Alpha: Die neue for-Loop-Maschinerie

Twig 4.0 Alpha: Die neue for-Loop-Maschinerie

Nach 17 Jahren erhält die for-Schleife in Twig 4.0 einen kompletten Rebuild, der subtile Fehlerquellen bei Generatoren und Iteratoren endlich beseitigt. Die neue Engine bringt nicht nur die schmerzlich vermisste for-if-Bedingung zurück, sondern führt auch strengere Fehlerprüfungen und eine modernisierte API für Extension-Entwickler ein. Erfahren Sie, welche Breaking Changes auf Sie zukommen und wie der Upgrade-Pfad für Symfony-Teams und Agenturen aussieht.

Dennis Schwenker-Sanders 8 Min. Lesezeit

Twig 4.0 Alpha: Die neue for-Loop-Maschinerie

Twig besteht seit 17 Jahren. Die for-Schleife in Twig war in diesen 17 Jahren eine der stabilsten Konstanten des PHP-Template-Ökosystems. Sie war auch eine der subtilsten Fehlerquellen: loop.last funktionierte nicht zuverlässig mit Generatoren, for...if-Bedingungen wurden in Twig 3.0 ersatzlos gestrichen, und loop.length auf einem nicht-zählbaren Iterator lieferte leise leere Ausgaben, statt einen klaren Fehler zu werfen. Twig 4.0 baut die gesamte Loop-Maschinerie neu.

Was Sie in 8 Minuten erfahren:

  1. Was Fabien Potencier mit "I rebuilt the whole loop machinery" konkret meint und was das für Template-Autoren bedeutet
  2. Welche Breaking Changes Twig 4.0 wirklich mitbringt und welche Entwarnung gilt
  3. Was Extension-Autoren jetzt prüfen müssen und wie der Upgrade-Pfad von 3.x auf 4.0 aussieht

Twig 4.0.0-alpha1 wurde am 17. Mai 2026 veröffentlicht. PHP 8.2 ist das Minimum. Die Alpha ist für Production noch nicht empfohlen, aber für Testing und Extension-Autoren ab sofort relevant. Fabien Potencier hat die Änderungen in zwei Blog-Posts auf symfony.com dokumentiert: "New in Symfony 8.1: A New for Loop for Twig 4.0" und "New in Twig 4.0: Expression Parsers". Dieser Artikel fasst zusammen, was für Symfony-Teams und Agenturen wichtig ist.

Twig 4.0 Alpha: Was ändert sich?


Bereich

Was ändert sich

Betrifft

Migrationsbedarf

for-Schleife (Loop-Maschinerie)

Kompletter Rebuild, Look-Ahead-Mechanismus

Alle Templates mit for

Keine Deprecations auf 3.x

loop.last mit Iteratoren

Funktioniert jetzt mit Generatoren und Traversables

Generator-basierte Loops

Kein Handlungsbedarf

for...if-Bedingung

Zurückgekehrt (in 3.0 entfernt)

Template-Autoren

Kein Handlungsbedarf

loop.length/revindex auf non-countable

Wirft jetzt klaren Error statt leerer Ausgabe

Alle die loop.length nutzen

Templates prüfen

Expression-Parser (getOperators())

Entfällt, neue API: getExpressionParsers()

Extension-Autoren mit eigenen Operatoren

Extension-Code anpassen

Sandbox SecurityPolicy

Strengere Defaults, isAlwaysAllowedInSandbox()

Projekte mit Sandbox

Strict-Mode auf 3.x testen

Betrifft Sie das? Schnelltest in 30 Sekunden

Sofort prüfen wenn: Sie eigene Twig-Extensions mit getOperators() oder benutzerdefinierten Operatoren entwickeln. Die API entfällt in Twig 4.0.

Templates prüfen wenn: Sie loop.length, loop.revindex oder loop.revindex0 in Schleifen nutzen, die über Generator-Outputs oder nicht-zählbare Iteratoren iterieren.

Keine sofortige Aktion nötig wenn: Ihre Templates ausschließlich Arrays und Doctrine Collections iterieren. Das Twig-3.x-Verhalten bleibt vollständig kompatibel.

Twig-Extension mit eigenen Operatoren?

Die getOperators()-API entfällt in Twig 4.0. Ich helfe Ihnen einzuschätzen, welche Extensions angepasst werden müssen und was das bedeutet.

  • Twig-Extensions seit Version 1.x
  • Symfony-Template-Architektur aus der Praxis
Kostenlosen Check anfragen →

⏱️ Antwort binnen 24 Stunden

Was steckt hinter dem for-Loop-Rebuild?

Die fundamentale Frage bei der alten for-Loop-Implementierung: Woher weiß Twig, ob der aktuelle Iterationsschritt der letzte ist? Bei Arrays ist das trivial, die Länge ist bekannt. Bei Generatoren und beliebigen Traversable-Objekten ist es unmöglich, ohne einen zusätzlichen Trick.

Potencier hat diesen Trick implementiert: Die neue Loop-Maschinerie liest einen Schritt voraus (Look-Ahead). Sie fetcht den nächsten Wert aus dem Iterator, bevor sie den aktuellen rendert. Wenn der Look-Ahead keinen Wert mehr liefert, weiß Twig: Der aktuelle Schritt ist der letzte. loop.last ist damit korrekt für jeden Iterator, nicht nur für Arrays.

{# Twig 4.0: loop.last funktioniert jetzt mit Generatoren #}
{% for item in generatorFunction() %}
    {{ item.name }}
    {% if not loop.last %}, {% endif %}  {# Kein nachgestelltes Komma mehr #}
{% endfor %}

{# Das war das klassische Problem in Twig 3.x: #}
{# loop.last auf Generatoren lieferte immer false #}
{# Ergebnis: immer ein nachgestelltes Komma nach dem letzten Element #}

Das erklärt auch, warum loop.length, loop.revindex und loop.revindex0 jetzt auf nicht-zählbaren Iteratoren einen klaren Fehler werfen. Diese Werte setzen eine bekannte Gesamtlänge voraus. Ein Generator hat keine Gesamtlänge, bevor er vollständig abgearbeitet ist. Twig 3.x hat hier stillschweigend leere Werte geliefert, ein bekannter Bug-Magnet für nachgestellte Kommas und fehlende Trennzeichen in Templatesn.

Was bringt die Rückkehr von for...if?

In Twig 3.0 wurde die for...if-Bedingung entfernt. Der Grund damals: Sie verhielt sich überraschend im Zusammenspiel mit loop.index und loop.length. Wenn man 10 Elemente hatte, aber nur 3 die Bedingung erfüllten, was war dann loop.index? Der Index im Original-Array oder der Index der gefilterten Elemente?

Twig 3.0 hatte sich für "entfernen statt dokumentieren" entschieden. Twig 4.0 kehrt zurück, mit klarer Semantik: loop.*-Variablen beziehen sich auf die gefilterte Sammlung.

{# Twig 4.0: for...if zurück #}
{% for user in users if user.active %}
    {{ loop.index }}. {{ user.name }}  {# Index der aktiven User, nicht aller User #}
{% else %}
    Keine aktiven User gefunden.
{% endfor %}

Was viele unterschätzen: Die else-Klausel funktioniert jetzt auch korrekt im Zusammenspiel mit for...if. In Twig 3.x war das ein häufiger Fehler: {% else %} zeigte den Fallback, wenn die ursprüngliche Sammlung leer war, nicht wenn alle Elemente herausgefiltert wurden.

KurzDer Loop-Rebuild macht loop.last zuverlässig für jeden Iterator. for...if kehrt zurück mit klarer Semantik. Keine Deprecations auf dem 3.x-Branch für Template-Autoren.

Was müssen Extension-Autoren jetzt tun?

Hier liegt der eigentliche Handlungsbedarf: Der Expression-Parser wurde neu geschrieben, basierend auf Vaughan Pratts "Top Down Operator Precedence" (einem der einflussreichsten Parser-Algorithmen der Informatik). Das Ergebnis ist ein saubererer, besser erweiterbarer Parser.

Der Breaking Change: Die bisherige getOperators()-Methode in AbstractExtension entfällt. Sie wird ersetzt durch getExpressionParsers() und die neue Methode getOperatorTokens().

// Twig 3.x: getOperators() für eigene Operatoren
class MyExtension extends AbstractExtension
{
    public function getOperators(): array
    {
        return [
            [/* Unary operators */],
            [/* Binary operators */],
        ];
    }
}

// Twig 4.0: neue API
class MyExtension extends AbstractExtension
{
    public function getExpressionParsers(): array
    {
        // Gibt ExpressionParser-Objekte zurück
        return [new MyCustomOperatorParser()];
    }

    public function getOperatorTokens(): array
    {
        // Registriert Tokens die als Operatoren erkannt werden
        return ['my_operator'];
    }
}

Für Standard-Symfony-Projekte, die nur Core-Twig-Features nutzen, ist das kein Problem. Für Teams, die eigene Twig-Extensions mit benutzerdefinierten Operatoren gebaut haben, ist das ein Migration-Task. Die Komplexität hängt davon ab, wie viele eigene Operatoren in Verwendung sind.

Wie ich im Twig-3.27-Artikel beschrieben habe, hat der Strict Mode für die SecurityPolicy auf 3.x eine wichtige Vorab-Testfunktion: Wer ihn jetzt aktiviert, bekommt das Twig-4.0-Sandbox-Verhalten bereits heute und kann Probleme frühzeitig identifizieren.

Jetzt auf Twig 3.x vorbereiten: Aktivieren Sie den Strict Mode der SecurityPolicy auf Ihrem Twig-3.x-Setup, um das 4.0-Verhalten heute schon zu testen. Und: loop.length/revindex auf Generatoren in Staging provozieren, bevor 4.0 stable wird.

KurzExtension-Autoren mit getOperators(): Migration auf getExpressionParsers() und getOperatorTokens() einplanen. Template-Autoren ohne eigene Extensions: keine Aktion nötig.

⚡ Twig-Extension-Audit vor 4.0?

Ich prüfe welche Ihrer Extensions die neue API benötigen und begleite die Migration auf Twig 4.0 sobald GA erscheint.

  • Twig-Extensions und Custom-Operators aus der Praxis
  • Symfony-Template-Stack seit Jahren im Einsatz
Audit besprechen →

⏱️ Antwort binnen 24 Stunden

📞 Oder direkt anrufen: 04481 - 9099658

Was bedeutet das für bestehende Projekte?

Die gute Nachricht zuerst: Potenciers eigene Aussage ist eindeutig: "The for rework introduces no deprecations on the 3.x branch: a template that runs deprecation-free on Twig 3 renders identically on Twig 4.0, with the lone exception that reading loop.length, loop.revindex, or loop.revindex0 on a non-countable iterator now raises a clear error instead of producing empty output."

Das ist eine außerordentlich saubere Migration für Template-Autoren. Wenn Ihre Templates auf Twig 3.x ohne Deprecation-Warnings laufen, laufen sie auch auf Twig 4.0, mit einer einzigen Ausnahme.

Welche Templates müssen geprüft werden?

Twig kennt keine statische Analyse. Das heißt: Der einzige Weg, Loop-Probleme zu finden, ist ein Runtime-Test. Meine Empfehlung für die Vorbereitung:

Schritt 1: Alle Templates suchen, die loop.length, loop.revindex oder loop.revindex0 nutzen:

# Alle Templates nach loop.length/revindex suchen:
$ grep -r "loop\.length\|loop\.revindex" templates/

# In Symfony:
$ find templates/ -name "*.html.twig" -exec grep -l "loop\.length\|loop\.revindex" {} \;

Schritt 2: Für jede gefundene Stelle prüfen: Wird über ein Array oder eine Doctrine Collection iteriert (zählbar) oder über einen Generator, einen lazy Iterator oder ein Traversable-Objekt (nicht-zählbar)?

Schritt 3: Strict Mode der SecurityPolicy auf Twig 3.x aktivieren (falls Sandbox im Einsatz) und Staging-Tests durchführen.

Als Symfony-Entwickler mit Fokus auf Template-Architektur sehe ich eine Regel, die sich bewährt hat: Generator-basierte Template-Daten sollten immer über Doctrine ArrayCollection oder einen explizit zählbaren Wrapper an Twig übergeben werden, wenn loop.*-Variablen genutzt werden. Twig 4.0 macht diese Empfehlung verbindlich.

Aus der Praxis: Was Template-Bugs wirklich kostet

Aus der Praxis

Was mir bei Code-Reviews und Einarbeitungen in Bestandssysteme häufig begegnet: Das nachgestellte Komma-Problem ist ein Klassiker. Eine Liste rendert korrekt in 99% der Fälle. Im 1%-Fall, wenn ein Service statt eines Arrays einen Generator zurückgibt, erscheint ein zusätzliches Komma nach dem letzten Element. Das ist schwer zu reproduzieren, weil es vom Datentyp der zurückgegebenen Sammlung abhängt. Twig 4.0 macht solche stillen Fehler zu expliziten Exceptions. Das ist in der Entwicklung lästiger, in Production deutlich sicherer.

Für Projekte, die nach Twig 4.0 GA migrieren wollen: Der Zeitplan ist noch nicht kommuniziert. Twig 4.0.0-alpha1 erschien am 17. Mai 2026. Bei Twig-Versionshistorie (3.0 erschien im November 2020) ist mit einem GA-Release nicht vor Ende 2026 zu rechnen. Das gibt ausreichend Zeit für eine strukturierte Vorbereitung.

Zusammenfassung

Loop-Rebuild: loop.last funktioniert jetzt mit jedem Iterator. Look-Ahead-Mechanismus. Keine Deprecations für Template-Autoren auf dem 3.x-Branch.

for...if zurück: Mit klarer Semantik (loop.* bezieht sich auf gefilterte Sammlung). else funktioniert korrekt mit gefilterten Ergebnissen.

Einzige Ausnahme: loop.length, loop.revindex, loop.revindex0 auf nicht-zählbaren Iteratoren werfen jetzt einen klaren Error.

Extension-Autoren: getOperators() entfällt. Migration auf getExpressionParsers() und getOperatorTokens() erforderlich.

Vorbereitung jetzt: Strict Mode auf 3.x aktivieren. Templates nach loop.length/revindex durchsuchen. Generator-basierte Daten auf zählbare Wrapper prüfen.

Twig-Templates und Extensions: Sie wissen, was zu prüfen ist.

Loop-Checks, Extension-Migration, Strict-Mode-Testing. Lassen Sie uns klären, was für Ihr Projekt konkret zu tun ist.

  • Twig-Template-Architektur seit Version 1.x
  • Custom Extensions und Operator-Migration
  • Symfony-Template-Stack aus der Praxis
Nächsten Schritt klären →

Häufige Fragen

Muss ich meine Twig-Templates für 4.0 umschreiben?

In den meisten Fällen nein. Fabien Potencier hat das klar kommuniziert: Ein Template, das auf Twig 3.x ohne Deprecation-Warnings läuft, rendert auf Twig 4.0 identisch, mit einer Ausnahme. Wenn Sie loop.length, loop.revindex oder loop.revindex0 in Schleifen über nicht-zählbare Iteratoren wie Generatoren nutzen, erhalten Sie in Twig 4.0 einen klaren Fehler statt leerer Ausgabe.

Was ist der Look-Ahead-Mechanismus und beeinflusst er die Performance?

Der Look-Ahead liest in einer Schleife immer einen Iterator-Schritt voraus, um zu wissen, ob der aktuelle Schritt der letzte ist. Für Arrays ist das kein Unterschied. Bei Generatoren wird ein zusätzlicher current()/next()-Aufruf pro Iteration ausgeführt. Der Performance-Impact ist vernachlässigbar für typische Template-Schleifen. Bei extrem großen Datensätzen (Hunderttausende von Elementen) würde man ohnehin Pagination statt Volliteration nutzen.

Wann erscheint Twig 4.0 GA?

Noch kein GA-Datum kommuniziert. Twig 4.0.0-alpha1 erschien am 17. Mai 2026. Basierend auf der Twig-Versionshistorie (Twig 3.0 erschien November 2020, nach zwei Jahren Alpha/Beta) ist mit GA nicht vor Ende 2026 zu rechnen. Allerdings könnten Symfony 8.2 oder 8.3 Twig 4.0 als Minimum voraussetzen, was den GA-Termin beschleunigen kann.

Betrifft die Extension-API-Änderung auch Filter und Funktionen?

Nein. Die Änderung betrifft nur Extensions, die eigene Operatoren über getOperators() registrieren. Custom Filters (getFilters()), Functions (getFunctions()), Tests (getTests()) und Tags (getTokenParsers()) bleiben unverändert. Die allermeisten Twig-Extensions nutzen keine benutzerdefinierten Operatoren. Überprüfen Sie Ihre Extensions mit grep -r "getOperators" vendor/.

Wie teste ich Twig 4.0 heute schon in meinem Projekt?

Zwei Wege: Erstens, Twig 4.0.0-alpha1 in einem separaten Branch oder Staging-Umgebung installieren: composer require twig/twig:^4.0@alpha. Zweitens, den Strict Mode der SecurityPolicy auf Twig 3.x aktivieren (falls Sie die Sandbox nutzen), um das verschärfte 4.0-Sandbox-Verhalten zu testen, ohne auf die Alpha upgraden zu müssen.

Artikel teilen: