Variablen-Referenz
Alles, was ein Theme in Liquid sehen kann — 91 Variablen in 15 Gruppen, mit Typ, Beschreibung und der Angabe, wo sie verfügbar sind.
Diese Seite wird gegen den Code abgeglichen: ein Test vergleicht die Liste bei jedem Durchlauf mit src/lib/theme/theme-context.ts und schlägt fehl, sobald dort ein Feld dazukommt oder verschwindet, das hier nicht steht. Was Sie hier lesen, gibt es also auch.
Die vier Orte
„Wo verfügbar“ meint vier verschiedene Aufrufe des Renderers. Die globalen Objekte stehen in allen vieren; section gibt es nur im Abschnitt und content_for_layout nur im Layout. Das ist der häufigste Grund für einen Abschnitt, der leer bleibt: ein {{ section.settings.x }} im Layout gibt still nichts aus.
Layout
layout/theme.liquid
Abschnitt
sections/*.liquid
Asset
assets/*.liquid, z. B. theme.css.liquid
Vorlagen-JSON
Werte in templates/*.json
Schnipsel sind die Ausnahme
{% render %} öffnet einen EIGENEN, leeren Geltungsbereich: im Schnipsel ist restaurant nicht da, wenn man es nicht mitgibt. {% include %} erbt dagegen alles. Wer einen Schnipsel baut, der plötzlich nichts mehr ausgibt, hat fast immer diesen Unterschied vor sich.
{% comment %} render sieht NUR, was hier steht {% endcomment %}{% render 'karte', titel: restaurant.name, adresse: restaurant.address_full %} {% comment %} include erbt den ganzen Geltungsbereich {% endcomment %}{% include 'karte' %}Übersicht
- Global(ohne Präfix)19 Variablen
- Der Betriebrestaurant13 Variablen
- Ein Öffnungstagrestaurant.opening_hours[] · opening_hours_sets[].days[]3 Variablen
- Ein Öffnungszeiten-Satzopening_hours_sets[] · opening_hours_sets_by_id[kennung]3 Variablen
- Markebrand6 Variablen
- Reservierungs-Widgetwidget12 Variablen
- Reichweitenmessunganalytics3 Variablen
- Metadaten der Seitepage_meta2 Variablen
- Eine Speisekartemenus[] · menus_by_id[kennung]3 Variablen
- Ein Artikelproducts[] · products_by_id[kennung]10 Variablen
- Ein Navigationsmenünavigation_menus[] · navigation_menus_by_id[kennung] · navigation_menus_by_handle[kurzname]4 Variablen
- Ein Menüeintragnavigation_menus[].items[]4 Variablen
- Der Abschnittsection4 Variablen
- Ein Blocksection.blocks[]3 Variablen
- Vom Renderer ergänzt(ohne Präfix)2 Variablen
Alle Variablen
91 Variablen
Global
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- (ohne Präfix)
Diese Namen stehen ohne Präfix zur Verfügung, in jeder Vorlage, jedem Abschnitt und jedem Liquid-Asset. Sie kommen aus `buildContext()` und werden vom Renderer als Erlaubnisliste durchgereicht — was dort nicht steht, ist in Liquid still `nil`.
restaurant
Objekt
Die Stammdaten des Betriebs: Name, Anschrift, Kontakt, Logo, Öffnungszeiten.
Der Betrieb{{ restaurant.name }}settings
Zuordnung (Kennung → Wert)
Die Theme-Einstellungen. Zusammengesetzt aus den Vorgaben des Schemas, den gespeicherten Werten des Theme-Editors und den Marken-Werten aus dem Einrichtungsassistenten — in dieser Rangfolge, gespeicherte Werte gewinnen.
{{ settings.color_accent }}brand
Objekt
Farben und Schriften aus dem Einrichtungsassistenten. Sie speisen die Standardwerte von `settings`; direkt gelesen werden sie dort, wo ein Theme die Marke unabhängig von seinen Einstellungen braucht.
Marke{{ brand.primary }}widget
Objekt
Alles für den Einbau des Reservierungs-Widgets: Adressen, Darstellungsart, Farben.
Reservierungs-Widget{{ widget.embed_url }}analytics
Objekt
Die eigene, cookiefreie Reichweitenmessung. Das Layout bindet das Script nur ein, wenn `analytics.enabled` gilt.
Reichweitenmessung{% if analytics.enabled %}…{% endif %}page_title
Textkann fehlen
Der Titel der aufgerufenen Seite — aus `WebsitePage.seoTitle`, ersatzweise `WebsitePage.title`, ersatzweise der Name des Betriebs. Gehört in `<title>`.
<title>{{ page_title }}</title>page_meta
Objektkann fehlen
Titel und Beschreibung für die Metadaten der Seite. Fehlt auf Pfaden, zu denen es keine `WebsitePage` gibt.
Metadaten der Seitelocale
Text
Die gewählte Sprache, z. B. `de`. Es ist die angefragte Sprache, falls das Theme sie kennt, sonst die Standardsprache des Themes.
<html lang="{{ locale }}">locales
Zuordnung (Schlüssel → Text)
Die Übersetzungen der gewählten Sprache aus `locales/<sprache>.json`. Normalerweise nicht direkt gelesen, sondern über den Filter `| t`.
{{ 'header.book' | t }}now
Text (ISO-8601)
Der Zeitpunkt des Renderns, z. B. `2026-09-14T12:00:00.000Z`. Nützlich für Jahreszahlen im Fuß.
{{ now | date: "%Y" }}menus
Liste von Objekten
Die aktiven Speisekarten aus der Warenwirtschaft, in ihrer Sortierreihenfolge.
Eine Speisekarte{% for karte in menus %}{{ karte.name }}{% endfor %}menus_by_id
Zuordnung (Kennung → Objekt)
Dieselben Speisekarten, nach Kennung ansprechbar. Der Weg, wenn eine Abschnitts-Einstellung eine Karte auswählen lässt.
Eine Speisekarte{{ menus_by_id[section.settings.menu_id].name }}opening_hours_sets
Liste von Objekten
Alle aktiven Öffnungszeiten-Sätze, Standard zuerst. Ein Betrieb kann mehrere führen (Küche, Bar, Feiertage).
Ein Öffnungszeiten-Satzopening_hours_sets_by_id
Zuordnung (Kennung → Objekt)
Dieselben Sätze, nach Kennung ansprechbar.
Ein Öffnungszeiten-Satz{{ opening_hours_sets_by_id[section.settings.hours_id].title }}navigation_menus
Liste von Objekten
Die Navigationsmenüs aus Website › Menüs, nach Titel sortiert. Für Kopf- und Fusszeile.
Ein Navigationsmenünavigation_menus_by_id
Zuordnung (Kennung → Objekt)
Dieselben Menüs, nach Kennung ansprechbar.
Ein Navigationsmenünavigation_menus_by_handle
Zuordnung (Kurzname → Objekt)
Dieselben Menüs, nach Kurzname ansprechbar — der stabilere Weg, weil der Kurzname im Dashboard vergeben wird und über einen Umzug hinweg gleich bleibt.
Ein Navigationsmenü{% assign hauptmenue = navigation_menus_by_handle["main"] %}products
Liste von Objekten
Die aktiven Artikel der Warenwirtschaft, nach Titel sortiert. Für Speisekarten-Blöcke.
Ein Artikelproducts_by_id
Zuordnung (Kennung → Objekt)
Dieselben Artikel, nach Kennung ansprechbar.
Ein Artikel
Der Betrieb
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- restaurant
Die Stammdaten aus dem Dashboard. Fast alle Felder sind freiwillig ausgefüllt — ein Theme, das `{{ restaurant.tagline }}` ohne `{% if %}` ausgibt, zeigt bei der Hälfte der Betriebe eine leere Zeile.
restaurant.id
Text
Die interne Kennung des Betriebs. Selten gebraucht.
restaurant.name
Text
Der Name des Betriebs. Immer gesetzt.
{{ restaurant.name }}restaurant.slug
Text
Die öffentliche Kennung, wie sie in Adressen steht.
{{ restaurant.slug }}restaurant.description
Textkann fehlen
Die Beschreibung des Betriebs aus den Einstellungen.
restaurant.tagline
Textkann fehlen
Der Einzeiler unter dem Namen, z. B. „Wirtshaus seit 1904".
restaurant.email
Textkann fehlen
Die öffentliche E-Mail-Adresse.
restaurant.phone
Textkann fehlen
Die öffentliche Telefonnummer.
restaurant.website
Textkann fehlen
Eine hinterlegte eigene Adresse — nicht die von TacticTable erzeugte Website.
restaurant.address_full
Textkann fehlen
Die Anschrift in einer Zeile, aus Strasse, Zusatz, Postleitzahl, Ort und Land zusammengesetzt. Fehlt, wenn keiner dieser Teile ausgefüllt ist.
{{ restaurant.address_full }}restaurant.booking_url
Text (absolute Adresse)
Die vollständige Adresse der öffentlichen Buchungsstrecke. ABSOLUT, weil die Website unter einer anderen Herkunft läuft als die App — ein relativer Pfad liefe dort ins Leere.
<a href="{{ restaurant.booking_url }}">Tisch reservieren</a>restaurant.logo_url
Textkann fehlen
Adresse der Logodatei.
restaurant.icon_url
Textkann fehlen
Adresse des Symbols (Favicon, App-Kachel).
restaurant.opening_hours
Liste von Objekten
Die Öffnungszeiten des Standard-Satzes, IMMER sieben Einträge von Montag bis Sonntag — auch geschlossene Tage stehen darin. Weitere Sätze liegen unter `opening_hours_sets`.
Ein Öffnungstag{% for tag in restaurant.opening_hours %}…{% endfor %}
Ein Öffnungstag
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- restaurant.opening_hours[]
- opening_hours_sets[].days[]
Ein Wochentag. Die Zeiten sind bereits als Text gesetzt, inklusive der zweiten Spanne bei geteilten Tagen („11:30 – 14:00, 17:30 – 23:00") — ein Theme muss nichts zusammenbauen.
restaurant.opening_hours[].label
Text
Der deutsche Name des Wochentags: „Montag" … „Sonntag".
{{ tag.label }}restaurant.opening_hours[].closed
Wahrheitswert
Wahr, wenn an diesem Tag geschlossen ist — dann ist `times` leer. Der Grund, warum ein Theme hier ein `{% if %}` braucht.
{% if tag.closed %}geschlossen{% else %}{{ tag.times }}{% endif %}restaurant.opening_hours[].times
Text
Die Zeiten des Tages, fertig gesetzt. Leer, wenn geschlossen.
{{ tag.times }}
Ein Öffnungszeiten-Satz
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- opening_hours_sets[]
- opening_hours_sets_by_id[kennung]
Ein Betrieb kann mehrere Sätze führen — Küche, Bar, Frühstück. Der Standard-Satz steht zusätzlich direkt unter `restaurant.opening_hours`.
opening_hours_sets[].id
Text
Die Kennung. Das, was eine Abschnitts-Einstellung speichert, wenn sie einen Satz auswählen lässt.
opening_hours_sets[].title
Text
Der Name des Satzes, z. B. „Küche".
opening_hours_sets[].days
Liste von Objekten
Die sieben Wochentage, gleich aufgebaut wie `restaurant.opening_hours`.
Ein Öffnungstag
Marke
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- brand
Farben und Schriften aus dem Einrichtungsassistenten. Jedes Feld kann fehlen — ein Betrieb, der den Assistenten übersprungen hat, hat hier nichts. Ein Theme sollte deshalb `settings` lesen, in das diese Werte bereits als Vorgabe eingeflossen sind, und `brand` nur dort, wo es die Marke unabhängig von den eigenen Einstellungen braucht.
brand.primary
Text (Hex)kann fehlen
Die Hauptfarbe der Marke.
{{ brand.primary | default: "#0f172a" }}brand.accent
Text (Hex)kann fehlen
Die Akzentfarbe.
brand.background
Text (Hex)kann fehlen
Die Grundfläche.
brand.text
Text (Hex)kann fehlen
Die Schriftfarbe.
brand.font_headline
Textkann fehlen
Der Name der Überschriften-Schrift, z. B. `Playfair Display`.
{{ brand.font_headline | font_url_family }}brand.font_body
Textkann fehlen
Der Name der Fliesstext-Schrift.
Reservierungs-Widget
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- widget
Alles, was der Einbau der Buchungsstrecke braucht. Die beiden Adressen sind ABSOLUT und müssen es sein: die Website läuft unter der Subdomain des Betriebs oder unter dessen eigener Domain, der Widget-Loader leitet aus seiner eigenen Adresse die Herkunft für iFrame und Konfiguration ab.
widget.display_mode
Text (`embed` oder `floating`)
Eingebettet im Seitenfluss oder als schwebender Knopf. Steuert, welchen der beiden Einbauten das Theme rendert.
{% if widget.display_mode == "floating" %}…{% endif %}widget.embed_url
Text (absolute Adresse)
Die Adresse der Buchungsstrecke — das Ziel des iFrames.
<iframe src="{{ widget.embed_url }}"></iframe>widget.loader_url
Text (absolute Adresse)
Die Adresse des Widget-Skripts. Muss auf die App zeigen, nicht auf die Website.
<script src="{{ widget.loader_url }}" defer></script>widget.slug
Text
Die Kennung des Betriebs, die das Widget mitgibt.
widget.floating_button_text
Text
Die Beschriftung des schwebenden Knopfes. Vorgabe: „Tisch reservieren".
widget.floating_position
Text
Die Ecke, z. B. `bottom-right`. Vorgabe: `bottom-right`.
widget.floating_offset_x
Zahl (px)
Abstand zum Seitenrand. Vorgabe: 20.
widget.floating_offset_y
Zahl (px)
Abstand zum unteren Rand. Vorgabe: 20.
widget.floating_size
Zahl (px)
Die Kantenlänge des Knopfes. Vorgabe: 56.
widget.floating_icon_url
Textkann fehlen
Ein eigenes Symbol im Knopf. Fehlt, wenn keines hinterlegt ist.
widget.primary_color
Text (Hex)
Die Hauptfarbe des Widgets. Vorgabe: `#0f172a`.
widget.accent_color
Text (Hex)
Die Akzentfarbe des Widgets. Vorgabe: `#3b82f6`.
Reichweitenmessung
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- analytics
Die eigene, cookiefreie Messung — unabhängig von GTM, GA4 und Meta, die aus denselben Einstellungen stammen, aber eine Einwilligung brauchen. Das Layout bindet das Skript NUR ein, wenn `enabled` gilt.
analytics.enabled
Wahrheitswert
Ob gemessen werden darf. Fehlt die Einstellung im Dashboard, gilt der Schema-Standard: eingeschaltet.
{% if analytics.enabled %}…{% endif %}analytics.script_url
Text (absolute Adresse)
Die Adresse des Zählskripts auf der App. Absolut, weil die Website auch unter einer Kunden-Wunschdomain läuft.
<script src="{{ analytics.script_url }}" defer></script>analytics.slug
Text
Die Kennung des Betriebs, unter der gezählt wird.
Metadaten der Seite
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- page_meta
Titel und Beschreibung für `<head>`. Sie stammen aus der `WebsitePage` zum aufgerufenen Pfad; gibt es dort keine, fehlt das ganze Objekt.
page_meta.title
Textkann fehlen
Der SEO-Titel, ersatzweise der Seitentitel.
<title>{{ page_meta.title | default: restaurant.name }}</title>page_meta.description
Textkann fehlen
Die SEO-Beschreibung. Fehlt, wenn sie nicht gepflegt ist — dann gehört kein leeres `<meta>` in die Seite.
{% if page_meta.description %}<meta name="description" content="{{ page_meta.description }}">{% endif %}
Ein Artikel
- Layout
- Abschnitt
- Asset
- Vorlagen-JSON
- products[]
- products_by_id[kennung]
Ein aktiver Artikel der Warenwirtschaft. Der Preis liegt in zwei Formen bereit: fertig gesetzt als `price` und roh als `price_cents` — Letzteres für eigene Formatierung oder Sortierung.
products[].id
Text
Die Kennung des Artikels.
products[].title
Text
Der Name des Gerichts.
{{ gericht.title }}products[].subtitle
Text
Die Unterzeile. Leerer Text, wenn nicht gepflegt.
products[].description
Text
Die Beschreibung. Leerer Text, wenn nicht gepflegt.
products[].price
Text
Der Bruttopreis, fertig gesetzt in deutscher Schreibweise, z. B. „14,90 €".
{{ gericht.price }}products[].price_cents
Zahl
Derselbe Preis in Cent. Für eigene Formatierung oder zum Sortieren.
products[].image_url
Text
Adresse des Bildes. Leerer Text, wenn keines hinterlegt ist.
products[].is_vegetarian
Wahrheitswert
Als vegetarisch gekennzeichnet.
products[].is_vegan
Wahrheitswert
Als vegan gekennzeichnet.
products[].is_gluten_free
Wahrheitswert
Als glutenfrei gekennzeichnet.
Der Abschnitt
- Abschnitt
- section
NUR innerhalb einer `sections/*.liquid` gesetzt. Im Layout, in einem Asset und in den Werten der Vorlagen-JSON ist `section` `nil` — ein `{{ section.settings.x }}` dort gibt still nichts aus, und das ist der häufigste Grund für einen leeren Abschnitt. Den Wert setzt entweder der `{% section %}`-Tag (Kopf und Fuss, aufgerufen aus dem Layout) oder die Renderschleife über `templates/<vorlage>.json`.
section.id
Text
Die Kennung des Abschnitts. Aus der Vorlage der Schlüssel unter `sections`, beim Aufruf über `{% section "header" %}` der Name der Datei. Gehört als `id` ins äusserste Element, damit Sprungziele funktionieren.
<section id="{{ section.id }}">section.type
Text
Der Typ des Abschnitts, also der Dateiname ohne Endung. ACHTUNG: nur gesetzt, wenn der Abschnitt aus der Vorlage kommt — beim Aufruf über `{% section %}` im Layout ist er `nil`.
section.settings
Zuordnung (Kennung → Wert)
Die Einstellungen dieses Abschnitts: die Vorgaben aus `{% schema %}`, überschrieben von dem, was in der Vorlage steht.
{{ section.settings.heading }}section.blocks
Liste von Objekten
Die Blöcke des Abschnitts, in der Reihenfolge aus `block_order`. Leere Liste, wenn der Abschnitt keine hat.
Ein Block{% for block in section.blocks %}…{% endfor %}
Ein Block
- Abschnitt
- section.blocks[]
Ein wiederholbarer Baustein innerhalb eines Abschnitts — eine Bildkachel, ein Gericht, ein Öffnungstag. Aufbau und Vorgaben kommen aus `blocks` im `{% schema %}` des Abschnitts.
section.blocks[].id
Text
Die Kennung des Blocks aus der Vorlage. Eindeutig innerhalb des Abschnitts.
section.blocks[].type
Text
Der Blocktyp, wie im Schema deklariert.
section.blocks[].settings
Zuordnung (Kennung → Wert)
Die Einstellungen dieses Blocks, Schema-Vorgaben und Vorlagenwerte zusammengeführt.
{{ block.settings.text }}
Vom Renderer ergänzt
- Layout
- Abschnitt
- (ohne Präfix)
Zwei Namen, die nicht aus `theme-context.ts` kommen, sondern vom Renderer selbst gesetzt werden.
content_for_layout
Text (HTML)
NUR im Layout. Die bereits gerenderten Abschnitte der Vorlage, aneinandergereiht. Fehlt dieser Ausdruck in `layout/theme.liquid`, ist jede Seite leer — das Layout rahmt dann nichts.
{{ content_for_layout }}sections
Zuordnung (Name → Abschnitt)
Alle Abschnitte des Themes nach ihrem Dateinamen, mit aufgelösten Einstellungen. Der `{% section %}`-Tag greift hier zu; ein Theme liest das selten direkt.
Der Abschnitt