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.id
  • page.name
  • page.title
  • page.url
  • page.httpUrl
  • page.path
  • page.template
  • page.created
  • page.modified
  • page.createdStr
  • page.modifiedStr
  • page.status
  • page.sort
  • page.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.isPublished
  • page.isHidden
  • page.isUnpublished
  • page.isTrash
  • page.isNew
  • page.hasChildren
  • page.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.parent
  • page.parents
  • page.rootParent
  • page.children
  • page.siblings
  • page.next
  • page.prev
  • page.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.images
  • page.image
  • page.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.url
  • img.httpUrl
  • img.filename
  • img.description
  • img.width
  • img.height
  • img.ext
  • img.filesize
  • img.webp.url
  • img.raw.url

Eigenschaften von Dateiobjekten

Typische Eigenschaften von Dateiobjekten umfassen:

  • file.url
  • file.httpUrl
  • file.filename
  • file.description
  • file.ext
  • file.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:

  • first
  • last
  • count
  • eq(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.id
  • user.name
  • user.title
  • user.email
  • user.displayName
  • user.isLoggedin
  • user.isGuest
  • user.isSuperuser
  • user.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.count
  • languages.current
  • languages.default
  • languages.isMultiLanguage
  • languages.all
  • languages.{name}

Beispiel:

{{#if languages.isMultiLanguage}}
  Current language: {{ languages.current.title }}
{{/if}}

Innerhalb von {{#languages}} stellt jedes Sprachelement üblicherweise bereit:

  • lang.id
  • lang.name
  • lang.title
  • lang.isDefault
  • lang.isCurrent
  • lang.url
  • lang.httpUrl
  • lang.locale

site

site liefert Seitenweit‑Werte.

Gängige Eigenschaften umfassen:

  • site.name
  • site.url
  • site.httpUrl
  • site.httpHost
  • site.locale
  • site.year
  • site.assets
  • site.templates
  • site.adminUrl
  • site.adminProfileUrl
  • site.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.timestamp
  • now.date
  • now.datetime
  • now.year
  • now.month
  • now.day

Beispiel:

<footer>&copy; {{ 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.index
  • loop.index1
  • loop.first
  • loop.last
  • loop.length
  • loop.even
  • loop.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.:

  • page
  • pages
  • user
  • languages
  • lang
  • site
  • now
  • attr
  • loop
  • this
  • @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-embed
  • data-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 / e
  • raw
  • upper
  • lower
  • capitalize
  • trim
  • truncate
  • nl2br
  • striptags
  • replace
  • split
  • slice
  • pad
  • wrap
  • slug

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:

  • number
  • currency
  • abs
  • round
  • ceil
  • floor

Beispiele:

{{ 1234567 | number(0, ".", ",") }}
{{ price | currency("$", 2) }}
{{ ratio | round(2) }}

Datums‑Filter

Gängige Datums‑Filter umfassen:

  • date
  • datetime
  • relative

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_encode
  • url

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:

  • join
  • first
  • last
  • count
  • length
  • reverse
  • sort
  • pluck
  • unique
  • batch
  • keys
  • values
  • merge

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:

  • static
  • dynamic
  • auto

Verwenden Sie:

  • static, wenn die Ausgabe weitgehend cache‑freundlich ist
  • dynamic, wenn die Ausgabe von benutzer‑ oder anfrage‑sensitivem Laufzeitzustand abhängt
  • auto, 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-embed
  • data-review-embed
  • data-fb-map
  • data-fb-map-field
  • data-component-*
  • data-form-ajax
  • data-variable
  • data-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:

  1. lade das zugehörige FaceFlow‑Objekt
  2. löse den aktuellen Render‑Kontext auf
  3. injiziere Root‑Level‑Felder und Kontextobjekte
  4. werte Feld‑Helfer‑Verträge aus
  5. werte Facet‑Ausdrücke und Block‑Helfer aus
  6. löse Variable‑Einbettungen auf
  7. löse verwaltete Laufzeit‑Marker wie Formulare, Reviews oder Karten auf
  8. 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

<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}}
{{#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:

  1. bestätigen Sie den Vertrag des zugehörigen Objekts
  2. bestätigen Sie die richtige Syntax‑Familie
  3. bestätigen Sie die verfügbaren Kontextobjekte
  4. reduzieren Sie das Template auf das kleinste reproduzierbare Fragment
  5. bauen Sie es dann wieder auf

Verwandte