Facet-Referenz
Facet-Referenz
Verwenden Sie diese Seite, wenn der grundlegende Syntaxleitfaden nicht mehr ausreicht und Sie tiefere Referenzinformationen zu Facet-Verhalten, Kontextobjekten, Helfer‑Verträgen und Rendering‑Regeln benötigen.
Diese Seite ist bewusst kompakt/technisch gehalten. Sie ist das technische Referenz‑Begleitdokument zu:
Was diese Seite abdeckt
Verwenden Sie diese Referenz, wenn Sie Details benötigen zu:
- Kontextobjekten und ihren gemeinsamen Eigenschaften
- Zugriffs‑Mustern für Seite, Medien und Sammlungen
- Helfer‑Verträgen für Bilder und Karten
- Filtern nach Kategorie
- Verhalten des Variable‑Systems
- Slots auf Layout‑Ebene
- verwalteten Datenattributen
- Medienreferenzen
- Rendering‑ und Sicherheitsregeln
Kontextobjekte
Facet‑Templates haben Zugriff auf einen kontrollierten Satz von Root‑Level‑Objekten. Welche Eigenschaften nützlich sind, hängt von der aktuellen Render‑Oberfläche ab, aber dasselbe mentale Modell gilt überall.
page
page ist das aktuelle Seitenobjekt im aktuellen Render‑Kontext.
Wichtige Seiten‑Eigenschaften
Gängige skalare Eigenschaften umfassen:
page.idpage.namepage.titlepage.urlpage.httpUrlpage.pathpage.templatepage.createdpage.modifiedpage.createdStrpage.modifiedStrpage.statuspage.sortpage.numChildren
Typische Verwendung:
<h1>{{ page.title }}</h1>
<p>Updated {{ page.modified | date("F j, Y") }}</p>Status‑ähnliche Eigenschaften
Gängige boolean‑artige Eigenschaften umfassen:
page.isPublishedpage.isHiddenpage.isUnpublishedpage.isTrashpage.isNewpage.hasChildrenpage.isEditable
Beispiel:
{{#if page.hasChildren}}
<p>This page has child pages.</p>
{{/if}}page.isEditable ist besonders nützlich für UI-Elemente, die nur für Bearbeiter der aktuellen Seite sichtbar sein sollen:
{{#if page.isEditable}}
<a href="{{ page.url }}?edit=1">Edit this page</a>
{{/if}}Relationale Eigenschaften
Facet stellt häufig relationale Zugriffe bereit wie:
page.parentpage.parentspage.rootParentpage.childrenpage.siblingspage.nextpage.prevpage.find
Beispiele:
{{ page.parent.title }}
{{ page.rootParent.title }}
{{#each page.children as="child"}}
<a href="{{ child.url }}">{{ child.title }}</a>
{{/each}}Medien‑Eigenschaften
Gängige medienorientierte Eigenschaften umfassen:
page.imagespage.imagepage.files
Beispiele:
{{#each page.images as="img"}}
<img src="{{ img.width(800).webp.url }}" alt="{{ img.description }}">
{{/each}}
{{#each page.files as="file"}}
<a href="{{ file.url }}">{{ file.filename }}</a>
{{/each}}Eigenschaften von Bildobjekten
Typische Eigenschaften von Bildobjekten umfassen:
img.urlimg.httpUrlimg.filenameimg.descriptionimg.widthimg.heightimg.extimg.filesizeimg.webp.urlimg.raw.url
Eigenschaften von Dateiobjekten
Typische Eigenschaften von Dateiobjekten umfassen:
file.urlfile.httpUrlfile.filenamefile.descriptionfile.extfile.filesize
Bild‑Transformationen
Page‑ und Query‑Bildobjekte unterstützen verkettete Transformationen:
{{ page.image.width(800) }}
{{ page.image.size(600, 400) }}
{{ page.image.size(600, 400).webp.url }}
{{ page.image.raw.url }}In Schleifen:
{{#each page.images as="img"}}
<img src="{{ img.size(400, 300).webp.url }}" alt="{{ img.description }}">
{{/each}}Sammlungs‑Methoden
Gängige Sammlungs‑Hilfsfunktionen umfassen:
firstlastcounteq(n)slice(start, length)
Beispiele:
{{ page.images.first.url }}
{{ page.images.count }}
{{ page.images.eq(2).url }}Dynamischer Feldzugriff
Benutzerdefinierte Seitenfelder können nach Name angesprochen werden:
{{ page.summary }}
{{ page.body }}
{{ page.headline }}
{{ page.field name="my_custom_field" }}Verwenden Sie dies, wenn die aktuelle Render‑Fläche wirklich von Seiten‑Daten abhängt. Verwenden Sie es nicht, um einen schwachen Component‑Feldvertrag zu kaschieren.
Lokalisierte URL
Facet kann lokalisierte URL‑Helfer für seitenbewusstes mehrsprachiges Rendering bereitstellen:
{{ page.localUrl lang="fr" }}
{{ page.localUrl lang="default" }}user
user repräsentiert den aktuellen Benutzerkontext.
Gängige Eigenschaften umfassen:
user.iduser.nameuser.titleuser.emailuser.displayNameuser.isLoggedinuser.isGuestuser.isSuperuseruser.language
Typische Verwendung:
{{#if user.isLoggedin}}
<span>Hello, {{ user.displayName }}!</span>
{{else}}
<a href="/login/">Log In</a>
{{/if}}pages
pages stellt query‑orientierte Helfer für skalare oder aggregierte Ausgaben bereit.
Gängige Muster umfassen:
pages.count selector="..."pages.first selector="..."pages.last selector="..."pages.titles selector="..." sep=", "pages.json selector="..."
Beispiele:
<p>Total posts: {{ pages.count selector="template=blog-post" }}</p>
<p>Categories: {{ pages.titles selector="template=category" sep=", " }}</p>Verwenden Sie {{#pages}}, wenn Sie eine Block‑Schleife benötigen. Verwenden Sie inline pages.*‑Helfer für skalare Ausgaben.
languages / lang
languages und lang geben das Sprachsystem frei.
Gängige Eigenschaften umfassen:
languages.countlanguages.currentlanguages.defaultlanguages.isMultiLanguagelanguages.alllanguages.{name}
Beispiel:
{{#if languages.isMultiLanguage}}
Current language: {{ languages.current.title }}
{{/if}}Innerhalb von {{#languages}} stellt jedes Sprachelement üblicherweise bereit:
lang.idlang.namelang.titlelang.isDefaultlang.isCurrentlang.urllang.httpUrllang.locale
site
site liefert Seitenweit‑Werte.
Gängige Eigenschaften umfassen:
site.namesite.urlsite.httpUrlsite.httpHostsite.localesite.yearsite.assetssite.templatessite.adminUrlsite.adminProfileUrlsite.adminLogoutUrl
Einstellungartige Zugriffe können ebenfalls verfügbar sein:
{{ site.setting key="company_name" }}
{{ site.setting key="phone" }}<a href="{{ site.adminUrl }}">Dashboard</a>
<a href="{{ site.adminProfileUrl }}">Profile</a>
<a href="{{ site.adminLogoutUrl }}">Log out</a>Verwenden Sie Site‑Einstellungen für stabile globale Werte, nicht für Inhalte, die zu einer Variable oder einem verwalteten Seitenobjekt gehören sollten.
now
now liefert aktuelle Zeitwerte.
Gängige Eigenschaften umfassen:
now.timestampnow.datenow.datetimenow.yearnow.monthnow.day
Beispiel:
<footer>© {{ now.year }} {{ site.name }}</footer>attr
attr gibt Werte frei, die in eine Variable übergeben wurden:
{{! Usage: [[my-widget title="Hello" color="blue"]] }}
<div style="color: {{ attr.color | default("black") }}">
<h3>{{ attr.title | default("Default Title") }}</h3>
</div>attr sollte klein und explizit bleiben. Wenn ein Fragment ein großes editierbares Datenmodell benötigt, ist wahrscheinlich eine Component statt einer Variable angebracht.
loop
loop ist innerhalb von Schleifenblöcken verfügbar wie:
{{#each}}{{#pages}}{{#languages}}
Gängige Eigenschaften:
loop.indexloop.index1loop.firstloop.lastloop.lengthloop.evenloop.odd
Beispiel:
{{#each page.children as="child"}}
<div class="{{#if loop.odd}}row-alt{{/if}}">
{{ loop.index1 }}. {{ child.title }}
</div>
{{/each}}this
Innerhalb von {{#each}} ist this das aktuelle Schleifenelement:
{{#each page.children}}
<a href="{{ this.url }}">{{ this.title }}</a>
{{/each}}this und ein benannter Alias verweisen normalerweise auf dasselbe aktuelle Element.
@index
@index ist eine Kurzform für loop.index.
Beispiel:
{{#each page.children as="child"}}
{{#if @index == 0}}
<h2>{{ child.title }}</h2>
{{else}}
<p>{{ child.title }}</p>
{{/if}}
{{/each}}Komponenten‑Root‑Level‑Felder
In Component‑Templates werden die Felder der aktuellen Component‑Instanz oft als Root‑Level‑Variablen injiziert:
<h1>{{ title }}</h1>
{{#if showGallery}}
<div class="gallery">
{{#each images as="img"}}
<img src="{{ img.url }}">
{{/each}}
</div>
{{/if}}Das ist einer der Gründe, warum Component‑Templates sich einfacher anfühlen als generische Seiten‑Templates.
Reservierte Namen sollten nicht leichtfertig als benutzerdefinierte Feldnamen wiederverwendet werden, wenn sie mit Kern‑Kontextobjekten kollidieren würden, wie z. B.:
pagepagesuserlanguageslangsitenowattrloopthis@index
Referenz der Component‑Feldhelfer
Facet arbeitet mit mehreren Component‑spezifischen Helfer‑Verträgen, die nicht identisch sind mit generischem {{ expr }}‑Output.
Helfer für Einzelbild‑Felder
Einzelne image‑Felder unterstützen typischerweise:
{field}{field.raw}{field.webp}{field.name}{field.description}{field.width(N)}{field.width(N).webp}{field.height(N)}{field.height(N).webp}{field.size(W,H)}{field.size(W,H).webp}
Beispiel:
<img src="{hero.width(1200).webp}" alt="{hero.description}">
<a href="{photo.raw}" download>Download original</a>Helfer für Multi‑Image‑Felder
Innerhalb von {{#each gallery}} unterstützen images‑Einträge typischerweise:
{{this}}{{this.raw}}{{this.webp}}{{this.name}}{{this.description}}{{this.width(N)}}{{this.width(N).webp}}{{this.height(N)}}{{this.height(N).webp}}{{this.size(W,H)}}{{this.size(W,H).webp}}
Beispiel:
{{#each gallery}}
<figure>
<img src="{{this.width(600).webp}}" alt="{{this.description}}">
<figcaption>{{this.name}}</figcaption>
</figure>
{{/each}}Helfer für Map‑Felder
map‑Felder unterstützen typischerweise:
{field}{field.width(N)}{field.height(N)}{field.size(W,H)}
Beispiele:
{officeLocation}
{officeLocation.width(600)}
{officeLocation.size(800,500)}Verwenden Sie map nur für strukturierte Standortdaten, nicht für einfachen Adresstext.
Verträge für verwaltete Einbettungen
Verwaltete Workflow‑Einbettungen verwenden typischerweise:
data-form-embeddata-review-embed
Beispiele:
<div data-form-embed="enterprise-demo-request"></div>
<div data-review-embed="customer-success-reviews"></div>
<div data-form-embed="{contactForm}"></div>
<div data-review-embed="{serviceReview}"></div>Verwenden Sie feste IDs für templates‑eigene Workflows und feldgestützte Werte für vom Autor auswählbare Workflows.
Filter‑Referenz
Filter transformieren Werte vor der Ausgabe. Die wichtigste Regel ist einfach:
- Verwenden Sie Filter zur Formatierung
- Verwenden Sie Filter nicht, um ein schwaches Objektmodell zu verbergen
String‑Filter
Gängige String‑Filter umfassen:
escape/erawupperlowercapitalizetrimtruncatenl2brstriptagsreplacesplitslicepadwrapslug
Beispiele:
{{ page.title | upper }}
{{ page.body | striptags | truncate(200, "...") }}
{{ text | nl2br }}
{{ title | slug }}Standardwert‑Filter
default liefert einen Fallback, wenn die Eingabe fehlt oder null‑ähnlich im unterstützten Vertrag ist:
{{ page.subtitle | default("Untitled") }}Wenn das Verhalten bei leerer Zeichenfolge genau relevant ist, bevorzugen Sie einen expliziten ternären Ausdruck.
Zahlen‑Filter
Gängige Zahlen‑Filter umfassen:
numbercurrencyabsroundceilfloor
Beispiele:
{{ 1234567 | number(0, ".", ",") }}
{{ price | currency("$", 2) }}
{{ ratio | round(2) }}Datums‑Filter
Gängige Datums‑Filter umfassen:
datedatetimerelative
Beispiele:
{{ page.created | date("F j, Y") }}
{{ page.modified | datetime("Y-m-d H:i") }}
{{ page.modified | relative }}URL‑Filter
Gängige URL‑orientierte Filter umfassen:
url_encodeurl
Beispiele:
{{ page.title | url_encode }}
{{ website | url }}JSON‑Filter
Verwenden Sie json für sichere JSON‑Ausgabe:
{{ data | json }}Das ist nützlich, wenn das Template strukturierte Daten in HTML‑ oder Script‑orientierte Ausgaben einbetten muss.
Array‑ und Sammlungs‑Filter
Gängige Sammlungs‑Filter umfassen:
joinfirstlastcountlengthreversesortpluckuniquebatchkeysvaluesmerge
Beispiele:
{{ tags | pluck("title") | join(", ") }}
{{ page.children | count }}
{{ items | batch(4) }}Bild‑Filter
Gängiger Bild‑Filter:
size
Beispiel:
{{ page.image | size(600, 400) }}Hash‑Filter
Gängiger Hash‑Filter:
md5
Beispiel:
{{ user.email | md5 }}Variablen‑System
Variablen sind wiederverwendbare Template‑Fragmente, die überall dort eingebettet werden können, wo FaceFlow‑Rendering dies unterstützt.
Einbinden von Variablen
Grundlegendes Einbinden:
[[my-variable]]Mit Attributen:
[[my-widget title="Hello World" color="blue" count="5"]]Aufbau einer Variable
Eine Variable enthält typischerweise:
- HTML‑Template
- optionales CSS
- optionales JS
- optionale Attribute
- Cache‑Modus
Cache‑Modi
Gängige Modi umfassen:
staticdynamicauto
Verwenden Sie:
static, wenn die Ausgabe weitgehend cache‑freundlich istdynamic, wenn die Ausgabe von benutzer‑ oder anfrage‑sensitivem Laufzeitzustand abhängtauto, wenn die Engine basierend auf dem Verhalten der Variable entscheiden soll
Verschachtelte Variablen
Variablen können andere Variablen einbinden:
<footer>
[[copyright-notice year="2026"]]
[[social-links]]
</footer>Verwenden Sie Verschachtelung, um Wiederverwendung und Klarheit zu verbessern, nicht um tiefe, versteckte Abhängigkeitsketten zu schaffen.
Syntax auf Layout‑Ebene
Layoutorientierte Templates verlassen sich oft auf einige strukturelle Platzhalter:
{content}{header}{footer}{siteComponents}
Beispiel:
<body>
{header}
{siteComponents}
<main>
{content}
</main>
{footer}
</body>Diese Platzhalter gehören zur Layout‑ und Shell‑Komposition, nicht zur normalen Abschnitts‑Darstellung.
Datenattribute
Gängige runtime‑orientierte Datenattribute umfassen:
data-form-embeddata-review-embeddata-fb-mapdata-fb-map-fielddata-component-*data-form-ajaxdata-variabledata-loading
Verwenden Sie diese, wenn der Laufzeitvertrag sie ausdrücklich dokumentiert. Erfinden Sie nicht leichtfertig parallele Attribute.
Medienreferenzen
Einige FaceFlow‑Rendering‑Kontexte können verwaltete Medienreferenz‑Muster freigeben wie:
@image:filename@file:filename
Dies sind implementierungsseitige Repräsentationen verwalteter Assets. In verfassten Templates ziehen Sie die dokumentierten Helfer‑ oder Objekt‑Ausgabeformen vor, anstatt sich auf rohe Speicher‑Referenzen zu verlassen.
Rendering‑Pipeline
Eine praktische Facet‑Rendering‑Reihenfolge sieht üblicherweise so aus:
- lade das zugehörige FaceFlow‑Objekt
- löse den aktuellen Render‑Kontext auf
- injiziere Root‑Level‑Felder und Kontextobjekte
- werte Feld‑Helfer‑Verträge aus
- werte Facet‑Ausdrücke und Block‑Helfer aus
- löse Variable‑Einbettungen auf
- löse verwaltete Laufzeit‑Marker wie Formulare, Reviews oder Karten auf
- gib die finale Ausgabe zurück
Die wichtige Design‑Lehre ist, dass Component‑Feld‑Kurzschreibweisen, Facet‑Ausdrücke, Variable‑Einbettungen und verwaltete Laufzeit‑Marker zusammenhängen, aber nicht identisch sind.
Sicherheitsmodell
Facet ist als gesteuerte Template‑Schicht konzipiert und nicht als rohe Code‑Ausführungsumgebung.
Schlüsselregeln:
- keine beliebige serverseitige Codeausführung
- Root‑Objekte sind kontrolliert
- Filter und Block‑Typen sind auf einer Whitelist
- Query‑Verhalten ist eingeschränkt
- rohe Ausgabe sollte bewusst verwendet werden
Betrachten Sie dies als sandboxed Template‑Sprache, nicht als Fallback‑Skriptumgebung.
Praktische Gestaltungsregeln
- Bevorzugen Sie klare Objektgrenzen gegenüber cleverer Template‑Logik
- Halten Sie Template‑Logik flach
- Verwenden Sie Variablen für Fragmente und Components für Abschnittsverträge
- Verwenden Sie Lists, wenn Abfrage und Paginierung Teil des Vertrags sind
- Prüfen Sie jegliche Feld‑Helfer‑Syntax anhand der Feldreferenz, bevor Sie sie verwenden
- Prüfen Sie cache‑sensitiven Inhalt, bevor Sie Deferred‑Rendering einführen
Praxisbeispiele
Navigationsmenü
<nav>
<ul>
{{#pages selector="parent=1, sort=sort" as="item"}}
<li><a href="{{ item.url }}">{{ item.title }}</a></li>
{{/pages}}
</ul>
</nav>Blog‑Beitragsliste
{{#pages selector="template=blog-post, sort=-created, limit=6" as="post"}}
<article>
<h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
<p>{{ post.body | striptags | truncate(250) }}</p>
</article>
{{else}}
<p>No blog posts yet.</p>
{{/pages}}Mehrsprachiger Umschalter
{{#if languages.isMultiLanguage}}
{{#languages as="lang"}}
<a href="{{ lang.url }}">{{ lang.title }}</a>
{{/languages}}
{{/if}}Breadcrumbs
{{#each page.parents as="p"}}
<a href="{{ p.url }}">{{ p.title }}</a> /
{{/each}}
<span>{{ page.title }}</span>Cache‑sicherer Benutzerbegrüßung
{{#deferred skeleton-width="10rem" skeleton-height="2rem"}}
{{#if user.isLoggedin}}
<span>{{ user.displayName }}</span>
{{else}}
<a href="/login/">Sign In</a>
{{/if}}
{{/deferred}}FAQ
Wann sollte ich {{#pages}} vs. {{#each}} verwenden?
- Verwenden Sie
{{#each}}, wenn die Daten bereits im aktuellen Kontext vorhanden sind - Verwenden Sie
{{#pages}}, wenn das Template die Daten abfragen muss
Was ist der Unterschied zwischen {{ }} und {{{ }}}?
{{ ... }}ist escaped Ausgabe{{{ ... }}}ist rohe Ausgabe
Verwenden Sie standardmäßig escapte Ausgabe.
Kann ich Schleifen verschachteln?
Ja, aber nur, wenn das Objektmodell lesbar bleibt. Wenn verschachtelte Schleifen ein schwaches Inhalts‑Kontrakt kompensieren, stoppen Sie und überarbeiten Sie das Design.
Warum gibt ein Feld null oder eine leere Ausgabe zurück?
Häufige Ursachen:
- falscher Kontext
- falscher Feldname
- Verwendung der falschen Syntax‑Familie für das aktuelle Objekt
- Erwartung eines Helfers auf einem Feld, das diesen nicht unterstützt
Wie debugge ich Template‑Probleme am besten?
Beginnen Sie in dieser Reihenfolge:
- bestätigen Sie den Vertrag des zugehörigen Objekts
- bestätigen Sie die richtige Syntax‑Familie
- bestätigen Sie die verfügbaren Kontextobjekte
- reduzieren Sie das Template auf das kleinste reproduzierbare Fragment
- bauen Sie es dann wieder auf