Facet-referentie

Facet-referentie

Gebruik deze pagina wanneer de primaire syntaxisgids niet meer voldoende is en je diepgaander referentiemateriaal nodig hebt over Facet-gedrag, contextobjecten, helper-contracten en renderregels.

Deze pagina is opzettelijk compact. Het is de technische referentiebijlage bij:

Wat Deze Pagina Beslaat

Gebruik deze referentie wanneer je details nodig hebt over:

  • contextobjecten en hun veelvoorkomende eigenschappen
  • toegangspatronen voor pagina's, media en collecties
  • helper-contracten voor afbeeldingen en kaarten
  • filters per categorie
  • het Variabelensysteemgedrag
  • layout-niveau slots
  • beheerde data-attributen
  • mediareferenties
  • render- en beveiligingsregels

Contextobjecten

Facet-sjablonen hebben toegang tot een gecontroleerde set rootniveau-objecten. Welke eigenschappen nuttig zijn hangt af van de huidige renderoppervlakte, maar hetzelfde mentale model geldt overal.

page

page is het huidige pagina-object in de huidige rendercontext.

Kernpagina-eigenschappen

Veelvoorkomende scalare eigenschappen omvatten:

  • 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

Typisch gebruik:

<h1>{{ page.title }}</h1>
<p>Updated {{ page.modified | date("F j, Y") }}</p>

Status-achtige Eigenschappen

Veelvoorkomende boolean-achtige eigenschappen omvatten:

  • page.isPublished
  • page.isHidden
  • page.isUnpublished
  • page.isTrash
  • page.isNew
  • page.hasChildren
  • page.isEditable

Voorbeeld:

{{#if page.hasChildren}}
  <p>This page has child pages.</p>
{{/if}}

page.isEditable is vooral nuttig voor UI-elementen die alleen zichtbaar moeten zijn voor editors van de huidige pagina:

{{#if page.isEditable}}
  <a href="{{ page.url }}?edit=1">Edit this page</a>
{{/if}}

Relatie-eigenschappen

Facet maakt vaak relationele toegang beschikbaar zoals:

  • page.parent
  • page.parents
  • page.rootParent
  • page.children
  • page.siblings
  • page.next
  • page.prev
  • page.find

Voorbeelden:

{{ page.parent.title }}
{{ page.rootParent.title }}

{{#each page.children as="child"}}
  <a href="{{ child.url }}">{{ child.title }}</a>
{{/each}}

Media-eigenschappen

Veelvoorkomende media-gerichte eigenschappen omvatten:

  • page.images
  • page.image
  • page.files

Voorbeelden:

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

Afbeeldingsobject-eigenschappen

Typische afbeeldingsobjecteigenschappen omvatten:

  • img.url
  • img.httpUrl
  • img.filename
  • img.description
  • img.width
  • img.height
  • img.ext
  • img.filesize
  • img.webp.url
  • img.raw.url

Bestandobject-eigenschappen

Typische bestandobjecteigenschappen omvatten:

  • file.url
  • file.httpUrl
  • file.filename
  • file.description
  • file.ext
  • file.filesize

Afbeeldingstransformaties

Pagina- en query-afbeeldingsobjecten ondersteunen geketende transformaties:

{{ page.image.width(800) }}
{{ page.image.size(600, 400) }}
{{ page.image.size(600, 400).webp.url }}
{{ page.image.raw.url }}

In lussen:

{{#each page.images as="img"}}
  <img src="{{ img.size(400, 300).webp.url }}" alt="{{ img.description }}">
{{/each}}

Collectiemethoden

Veelvoorkomende collectie-helpers omvatten:

  • first
  • last
  • count
  • eq(n)
  • slice(start, length)

Voorbeelden:

{{ page.images.first.url }}
{{ page.images.count }}
{{ page.images.eq(2).url }}

Dynamische Veldtoegang

Aangepaste page-velden kunnen worden benaderd op naam:

{{ page.summary }}
{{ page.body }}
{{ page.headline }}
{{ page.field name="my_custom_field" }}

Gebruik dit wanneer de huidige renderoppervlakte echt afhankelijk is van paginaniveaugegevens. Gebruik het niet om een zwak Component-veldcontract te verbergen.

Gelokaliseerde URL

Facet kan gelokaliseerde URL-helpers blootstellen voor pagina-bewuste meertalige weergave:

{{ page.localUrl lang="fr" }}
{{ page.localUrl lang="default" }}

user

user vertegenwoordigt de huidige gebruikerscontext.

Veelvoorkomende eigenschappen omvatten:

  • user.id
  • user.name
  • user.title
  • user.email
  • user.displayName
  • user.isLoggedin
  • user.isGuest
  • user.isSuperuser
  • user.language

Typisch gebruik:

{{#if user.isLoggedin}}
  <span>Hello, {{ user.displayName }}!</span>
{{else}}
  <a href="/login/">Log In</a>
{{/if}}

pages

pages biedt query-georiënteerde helpers voor scalare of geaggregeerde outputs.

Veelvoorkomende patronen omvatten:

  • pages.count selector="..."
  • pages.first selector="..."
  • pages.last selector="..."
  • pages.titles selector="..." sep=", "
  • pages.json selector="..."

Voorbeelden:

<p>Total posts: {{ pages.count selector="template=blog-post" }}</p>
<p>Categories: {{ pages.titles selector="template=category" sep=", " }}</p>

Gebruik {{#pages}} wanneer je een block-lus nodig hebt. Gebruik inline pages.*-helpers voor scalare outputs.

languages / lang

languages en lang geven toegang tot het taalsysteem.

Veelvoorkomende eigenschappen omvatten:

  • languages.count
  • languages.current
  • languages.default
  • languages.isMultiLanguage
  • languages.all
  • languages.{name}

Voorbeeld:

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

Binnen {{#languages}} biedt elk taalitem doorgaans:

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

site

site levert waarden op siteniveau.

Veelvoorkomende eigenschappen omvatten:

  • site.name
  • site.url
  • site.httpUrl
  • site.httpHost
  • site.locale
  • site.year
  • site.assets
  • site.templates
  • site.adminUrl
  • site.adminProfileUrl
  • site.adminLogoutUrl

Instellingsachtige toegang kan ook beschikbaar zijn:

{{ 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>

Gebruik site-niveau instellingen voor stabiele globale waarden, niet voor content die zou moeten behoren tot een Variabele of een beheerd paginaniveau-object.

now

now levert actuele tijdwaarden.

Veelvoorkomende eigenschappen omvatten:

  • now.timestamp
  • now.date
  • now.datetime
  • now.year
  • now.month
  • now.day

Voorbeeld:

<footer>&copy; {{ now.year }} {{ site.name }}</footer>

attr

attr geeft waarden bloot die aan een Variabele worden doorgegeven:

{{! Usage: [[my-widget title="Hello" color="blue"]] }}
<div style="color: {{ attr.color | default("black") }}">
  <h3>{{ attr.title | default("Default Title") }}</h3>
</div>

attr moet klein en expliciet blijven. Als een fragment een groot bewerkbaar datamodel nodig heeft, is het waarschijnlijk beter om een Component te gebruiken in plaats van een Variabele.

loop

loop is beschikbaar binnen lusblokken zoals:

  • {{#each}}
  • {{#pages}}
  • {{#languages}}

Veelvoorkomende eigenschappen:

  • loop.index
  • loop.index1
  • loop.first
  • loop.last
  • loop.length
  • loop.even
  • loop.odd

Voorbeeld:

{{#each page.children as="child"}}
  <div class="{{#if loop.odd}}row-alt{{/if}}">
    {{ loop.index1 }}. {{ child.title }}
  </div>
{{/each}}

this

Binnen {{#each}} is this het huidige lusitem:

{{#each page.children}}
  <a href="{{ this.url }}">{{ this.title }}</a>
{{/each}}

this en een benoemde alias wijzen normaal gesproken naar hetzelfde huidige item.

@index

@index is een afkorting voor loop.index.

Voorbeeld:

{{#each page.children as="child"}}
  {{#if @index == 0}}
    <h2>{{ child.title }}</h2>
  {{else}}
    <p>{{ child.title }}</p>
  {{/if}}
{{/each}}

Component Root-Level Velden

In Component-sjablonen worden de velden van de huidige Component-instantie vaak geïnjecteerd als rootniveau-variabelen:

<h1>{{ title }}</h1>

{{#if showGallery}}
  <div class="gallery">
    {{#each images as="img"}}
      <img src="{{ img.url }}">
    {{/each}}
  </div>
{{/if}}

Dit is een van de redenen waarom Component-sjablonen eenvoudiger aanvoelen dan generieke paginaniveau-sjablonen.

Gereserveerde namen mogen niet lichtvaardig worden hergebruikt als aangepaste veldnamen als ze zouden botsen met kerncontextobjecten zoals:

  • page
  • pages
  • user
  • languages
  • lang
  • site
  • now
  • attr
  • loop
  • this
  • @index

Component Veld Helper Referentie

Facet werkt met meerdere Component-specifieke helper-contracten die niet hetzelfde zijn als algemene {{ expr }}-output.

Helpers voor Enkelvoudig Afbeeldingsveld

Enkelvoudige image-velden ondersteunen doorgaans:

  • {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}

Voorbeeld:

<img src="{hero.width(1200).webp}" alt="{hero.description}">
<a href="{photo.raw}" download>Download original</a>

Helpers voor Multi-image Velden

Binnen {{#each gallery}} ondersteunen items van images doorgaans:

  • {{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}}

Voorbeeld:

{{#each gallery}}
  <figure>
    <img src="{{this.width(600).webp}}" alt="{{this.description}}">
    <figcaption>{{this.name}}</figcaption>
  </figure>
{{/each}}

Map Veld Helpers

map-velden ondersteunen doorgaans:

  • {field}
  • {field.width(N)}
  • {field.height(N)}
  • {field.size(W,H)}

Voorbeelden:

{officeLocation}
{officeLocation.width(600)}
{officeLocation.size(800,500)}

Gebruik map alleen voor gestructureerde locatiegegevens, niet voor platte adreskopie.

Beheerde Embed-Contracten

Beheerde workflow-embeds gebruiken typisch:

  • data-form-embed
  • data-review-embed

Voorbeelden:

<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>

Gebruik vaste ids voor templates-beheerde workflows en veld-gedragen waarden voor door auteurs selecteerbare workflows.

Filterreferentie

Filters transformeren waarden vóór output. De belangrijkste regel is eenvoudig:

  • gebruik filters voor formattering
  • gebruik geen filters om een zwak objectmodel te verbergen

Stringfilters

Veelvoorkomende stringfilters omvatten:

  • escape / e
  • raw
  • upper
  • lower
  • capitalize
  • trim
  • truncate
  • nl2br
  • striptags
  • replace
  • split
  • slice
  • pad
  • wrap
  • slug

Voorbeelden:

{{ page.title | upper }}
{{ page.body | striptags | truncate(200, "...") }}
{{ text | nl2br }}
{{ title | slug }}

Filter voor Standaardwaarde

default levert een fallback wanneer de invoer ontbreekt of null-achtig is in het ondersteunde contract:

{{ page.subtitle | default("Untitled") }}

Als het exacte lege-tekenreeks-gedrag van belang is, geef dan de voorkeur aan een expliciete ternary.

Nummerfilters

Veelvoorkomende nummerfilters omvatten:

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

Voorbeelden:

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

Datumfilters

Veelvoorkomende datumfilters omvatten:

  • date
  • datetime
  • relative

Voorbeelden:

{{ page.created | date("F j, Y") }}
{{ page.modified | datetime("Y-m-d H:i") }}
{{ page.modified | relative }}

URL-filters

Veelvoorkomende URL-gerichte filters omvatten:

  • url_encode
  • url

Voorbeelden:

{{ page.title | url_encode }}
{{ website | url }}

JSON-filter

Gebruik json voor veilige JSON-output:

{{ data | json }}

Dit is nuttig wanneer de sjabloon gestructureerde data in HTML- of scriptgerichte output nodig heeft.

Array- en Collectiefilters

Veelvoorkomende collectiefilters omvatten:

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

Voorbeelden:

{{ tags | pluck("title") | join(", ") }}
{{ page.children | count }}
{{ items | batch(4) }}

Image Filter

Veelvoorkomend image-filter:

  • size

Voorbeeld:

{{ page.image | size(600, 400) }}

Hash-filter

Veelvoorkomend hash-filter:

  • md5

Voorbeeld:

{{ user.email | md5 }}

Variabelensysteem

Variabelen zijn herbruikbare sjabloonfragmenten die overal kunnen worden ingebed waar FaceFlow-rendering dat ondersteunt.

Variabelen Insluiten

Basis inclusie:

[[my-variable]]

Met attributen:

[[my-widget title="Hello World" color="blue" count="5"]]

Structuur van een Variabele

Een Variabele bevat typisch:

  • HTML-sjabloon
  • optionele CSS
  • optionele JS
  • optionele attributen
  • cache-modus

Cache-modi

Veelvoorkomende modi omvatten:

  • static
  • dynamic
  • auto

Gebruik:

  • static wanneer de output over het algemeen cachevriendelijk is
  • dynamic wanneer de output afhankelijk is van gebruikers- of request-gevoelige runtime-state
  • auto wanneer de engine moet kiezen op basis van het gedrag van de Variabele

Geneste Variabelen

Variabelen kunnen andere Variabelen bevatten:

<footer>
  [[copyright-notice year="2026"]]
  [[social-links]]
</footer>

Gebruik nesteling om hergebruik en duidelijkheid te verbeteren, niet om diepe verborgen afhankelijkheidsketens te creëren.

Layout-niveau Syntaxis

Lay-outgerichte sjablonen vertrouwen vaak op een paar structurele tijdelijke aanduidingen:

  • {content}
  • {header}
  • {footer}
  • {siteComponents}

Voorbeeld:

<body>
  {header}
  {siteComponents}
  <main>
    {content}
  </main>
  {footer}
</body>

Deze tijdelijke aanduidingen behoren tot lay-out- en shellcompositie, niet tot gewone sectieweergave.

Data-attributen

Veelvoorkomende runtime-gerichte data-attributen omvatten:

  • data-form-embed
  • data-review-embed
  • data-fb-map
  • data-fb-map-field
  • data-component-*
  • data-form-ajax
  • data-variable
  • data-loading

Gebruik deze wanneer het runtime-contract ze expliciet documenteert. Bedenk niet lichtvaardig parallelle attributen.

Mediareferenties

Sommige FaceFlow-rendercontexten kunnen beheerde mediareferentiepatronen blootstellen zoals:

  • @image:filename
  • @file:filename

Dit zijn implementatie-zijde representaties van beheerde assets. In geauthorde sjablonen heeft de voorkeur om de gedocumenteerde helper- of objectoutputvormen te gebruiken in plaats van te vertrouwen op ruwe opslagreferenties.

Rendering Pipeline

Een praktisch Facet-renderingorder ziet er meestal zo uit:

  1. load the owning FaceFlow object
  2. resolve the current render context
  3. inject root-level fields and context objects
  4. evaluate field helper contracts
  5. evaluate Facet expressions and block helpers
  6. resolve Variable embeds
  7. resolve managed runtime markers such as Forms, Reviews, or maps
  8. return final output

De belangrijke ontwerples is dat Component-veldafkortingen, Facet-expressies, Variabele-embeds en beheerde runtime-markers gerelateerd maar niet identiek zijn aan elkaar.

Beveiligingsmodel

Facet is ontworpen als een beheerde sjabloonlaag in plaats van een ruwe code-uitvoeringsomgeving.

Belangrijke regels:

  • geen willekeurige server-side code-uitvoering
  • rootobjecten worden gecontroleerd
  • filters en blocktypes staan op een whitelist
  • query-gedrag is beperkt
  • raw output moet bewust worden gebruikt

Behandel dit als een gesandboxte sjabloontaal, niet als een fallback-scriptingengine.

Praktische Ontwerpregels

  • geef de voorkeur aan duidelijke objectgrenzen boven slimme sjabloonlogica
  • houd sjabloonlogica ondiep
  • gebruik Variabelen voor fragmenten en Components voor sectiecontracten
  • gebruik Lists wanneer query en paginatie deel uitmaken van het contract
  • controleer de syntax van field-helpers tegen de veldreferentie voordat je ze gebruikt
  • beoordeel cache-gevoelige content voordat je deferred rendering introduceert

Cookbook-patronen

<nav>
  <ul>
    {{#pages selector="parent=1, sort=sort" as="item"}}
      <li><a href="{{ item.url }}">{{ item.title }}</a></li>
    {{/pages}}
  </ul>
</nav>

Blogpostlijst

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

Meertalige Schakelaar

{{#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-veilige Gebruikerswelkom

{{#deferred skeleton-width="10rem" skeleton-height="2rem"}}
  {{#if user.isLoggedin}}
    <span>{{ user.displayName }}</span>
  {{else}}
    <a href="/login/">Sign In</a>
  {{/if}}
{{/deferred}}

FAQ

Wanneer moet ik {{#pages}} gebruiken vs {{#each}}?

  • gebruik {{#each}} wanneer de data al aanwezig is in de huidige context
  • gebruik {{#pages}} wanneer het sjabloon de data moet opvragen

Wat is het verschil tussen {{ }} en {{{ }}}?

  • {{ ... }} is ge-escaped output
  • {{{ ... }}} is raw output

Gebruik standaard ge-escaped output.

Kan ik lussen nesten?

Ja, maar alleen wanneer het objectmodel leesbaar blijft. Als geneste lussen een zwak contentcontract compenseren, stop dan en herzie het ontwerp.

Waarom geeft een veld null of lege output terug?

Veelvoorkomende oorzaken:

  • verkeerde context
  • verkeerde veldnaam
  • gebruik van de verkeerde syntaxisfamilie voor het huidige object
  • het verwachten van een helper op een veld dat dat niet ondersteunt

Hoe moet ik sjabloonproblemen debuggen?

Begin in deze volgorde:

  1. bevestig het contract van het eigenaar-object
  2. bevestig de juiste syntaxisfamilie
  3. bevestig de beschikbare contextobjecten
  4. reduceer het sjabloon tot het kleinste reproduceerbare fragment
  5. bouw vanaf daar weer op

Gerelateerd