Teilstücke: render und include

Wiederverwendbares Markup aus snippets/ — und der eine Unterschied zwischen render und include, an dem die meisten Übersetzungen scheitern.

Für Entwickler

Voraussetzungen

  • Recht: website:write

Ein Teilstück ist eine Datei unter `snippets/` mit der Endung `.liquid`. Es hat kein Schema, keine Einstellungen und keinen Platz in einer Vorlage — es wird aus einem Abschnitt oder dem Layout heraus aufgerufen.

Gefunden wird es unter drei Schreibweisen: `"gericht-zeile"`, `"gericht-zeile.liquid"` und `"snippets/gericht-zeile"`. Ein Zugriff auf das Dateisystem des Servers ist dabei nicht möglich; nachgesehen wird ausschliesslich in den Teilstücken des Themes.

DER UNTERSCHIED, um den es geht: `{% render %}` gibt dem Teilstück einen LEEREN Geltungsbereich. Darin steht nur, was Sie ausdrücklich hereinreichen — kein `restaurant`, kein `settings`, kein `section`, kein `locales`. `{% include %}` dagegen reicht die gesamte Umgebung durch.

Die Folge, die am meisten Zeit kostet: Der Filter `t` findet seine Sprachdatei in einem `render`-Teilstück NICHT und gibt nur den Schlüssel zurück. Übersetzen Sie deshalb im aufrufenden Template und reichen Sie den fertigen Text herein — oder nehmen Sie an dieser Stelle `include`.

Die zweite Folge betrifft Zuweisungen: Ein `{% assign %}` innerhalb eines `include`-Teilstücks wirkt NACH AUSSEN weiter, bei `render` nicht. Das ist bequem und zugleich die Ursache für Werte, die sich unterwegs still ändern.

Empfehlung: `render` ist der Normalfall, weil abgekapselt. `include` nur dort, wo Sie die Umgebung wirklich brauchen — und dann mit dem Wissen, dass Zuweisungen hinausreichen.

ACHTUNG: Ein Teilstück, das es nicht gibt, bricht die ganze Seite ab. Das ist der Unterschied zu `{% section %}`, das einen unbekannten Abschnitt nur als HTML-Kommentar vermerkt.

Codebeispiele

snippets/gericht-zeile.liquid
Liquid
<li class="gericht">  <span class="name">{{ gericht.title | escape }}</span>  <span class="preis">{{ gericht.price }}</span></li>
Das Teilstück kennt nur, was hereingereicht wird — hier die Variable `gericht`. Alleine gerendert ergibt es die leere Hülle; das ist kein Fehler, sondern der Beweis für die Abkapselung.
Aufrufen und Werte hereinreichen
Liquid
<ul>{%- for gericht in products %}  {% render 'gericht-zeile', gericht: gericht %}{%- endfor %}</ul>
Die Parameter stehen hinter dem Dateinamen, durch Komma getrennt: `name: wert`. Ohne diese Übergabe wäre `gericht` im Teilstück nichts.
Die Kurzform für Listen
Liquid
<ul>{% render 'gericht-zeile' for products as gericht %}</ul>
Spart die Schleife. Innerhalb des Teilstücks steht dabei auch `forloop` zur Verfügung — anders als bei der Übergabe einzelner Parameter.
snippets/umgebung.liquid
Liquid
restaurant=[{{ restaurant.name }}] settings=[{{ settings.color_accent }}] section=[{{ section.id }}] t=[{{ 'fuss.geschlossen' | t }}]
Ein Messgerät: es zeigt, was im Teilstück ankommt. Auf oberster Ebene gerendert sieht es alles.
render kapselt ab, include nicht
Liquid
mit render: {% render 'umgebung' %}
mit include: {% include 'umgebung' %}
DAS ist der Unterschied in einer Zeile. `render` liefert vier leere Klammern — und deshalb gibt der Filter `t` dort nur den Schlüssel zurück. Wer aus einer anderen Liquid-Welt kommt, sucht diesen Fehler lange, weil nichts abbricht.
snippets/setzt-was.liquid
Liquid
{%- assign gesamt = 3 -%}gesetzt
Ein Teilstück, das eine Variable setzt — der Versuchsaufbau für das nächste Beispiel.
Zuweisungen aus include sickern nach aussen
Liquid
{% render 'setzt-was' %} nach render: [{{ gesamt }}]
{% include 'setzt-was' %} nach include: [{{ gesamt }}]
Nach `render` ist `gesamt` draussen weiterhin nichts, nach `include` steht dort die 3. Bei langen Layouts ist das die Ursache für Werte, die sich scheinbar von selbst ändern — und zugleich ein Kniff, wenn man es absichtlich will.
Drei Schreibweisen finden dasselbe Teilstück
Liquid
{% render 'gericht-zeile', gericht: products[0] %}
{% render 'gericht-zeile.liquid', gericht: products[0] %}
{% render 'snippets/gericht-zeile', gericht: products[0] %}
Alle drei landen bei `snippets/gericht-zeile.liquid`. Unterverzeichnisse innerhalb von `snippets/` werden dabei ebenfalls auf den Dateinamen zurückgeführt — zwei gleichnamige Teilstücke in verschiedenen Unterordnern sind deshalb keine gute Idee.
Ein fehlendes Teilstück bricht die ganze Seite ab
AusschnittLiquid
{% render 'gibt-es-nicht' %}
Ausschnitt: läuft nicht für sich allein — er gehört an die passende Stelle einer bestehenden Vorlage.NICHT prüfbar, weil es absichtlich abbricht: die Engine wirft `ENOENT: Failed to lookup "gibt-es-nicht"`. Es gibt keinen Weg, vorher zu fragen, ob ein Teilstück existiert — prüfen Sie den Namen also beim Umbenennen und beim Kopieren aus einem anderen Theme. Ein unbekannter ABSCHNITT verhält sich anders: der hinterlässt nur einen HTML-Kommentar.

Wo im Dashboard

/restaurant/[slug]/website/themes/[id]/code

Im Dashboard öffnen