Riferimento Facet
Riferimento Facet
Usa questa pagina quando la guida di sintassi primaria non è più sufficiente e hai bisogno di materiale di riferimento più approfondito sul comportamento di Facet, sugli oggetti di contesto, sui contratti degli helper e sulle regole di rendering.
Questa pagina è intenzionalmente densa. È il riferimento tecnico che accompagna:
Cosa Copre Questa Pagina
Usa questo riferimento quando hai bisogno di dettagli su:
- oggetti di contesto e loro proprietà comuni
- pattern di accesso a page, media e collection
- contratti degli helper per immagini e mappe
- filtri per categoria
- comportamento del sistema di Variabili
- slot a livello di layout
- attributi dati gestiti
- riferimenti ai media
- regole di rendering e sicurezza
Oggetti di Contesto
I template Facet hanno accesso a un insieme controllato di oggetti di root-level. Quali proprietà sono utili dipende dalla superficie di rendering corrente, ma lo stesso modello mentale si applica ovunque.
page
page è l'oggetto pagina corrente nel contesto di rendering attuale.
Proprietà Principali della Pagina
Le comuni proprietà scalari includono:
page.idpage.namepage.titlepage.urlpage.httpUrlpage.pathpage.templatepage.createdpage.modifiedpage.createdStrpage.modifiedStrpage.statuspage.sortpage.numChildren
Uso tipico:
<h1>{{ page.title }}</h1>
<p>Updated {{ page.modified | date("F j, Y") }}</p>Proprietà in Stile Stato
Comuni proprietà booleane includono:
page.isPublishedpage.isHiddenpage.isUnpublishedpage.isTrashpage.isNewpage.hasChildrenpage.isEditable
Esempio:
{{#if page.hasChildren}}
<p>This page has child pages.</p>
{{/if}}page.isEditable è particolarmente utile per elementi dell’interfaccia che dovrebbero apparire solo agli editor della pagina corrente:
{{#if page.isEditable}}
<a href="{{ page.url }}?edit=1">Edit this page</a>
{{/if}}Proprietà Relazionali
Facet espone comunemente accesso relazionale come:
page.parentpage.parentspage.rootParentpage.childrenpage.siblingspage.nextpage.prevpage.find
Esempi:
{{ page.parent.title }}
{{ page.rootParent.title }}
{{#each page.children as="child"}}
<a href="{{ child.url }}">{{ child.title }}</a>
{{/each}}Proprietà Media
Le comuni proprietà orientate ai media includono:
page.imagespage.imagepage.files
Esempi:
{{#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}}Proprietà dell'Oggetto Immagine
Le proprietà tipiche degli oggetti immagine includono:
img.urlimg.httpUrlimg.filenameimg.descriptionimg.widthimg.heightimg.extimg.filesizeimg.webp.urlimg.raw.url
Proprietà dell'Oggetto File
Le proprietà tipiche degli oggetti file includono:
file.urlfile.httpUrlfile.filenamefile.descriptionfile.extfile.filesize
Trasformazioni Immagine
Gli oggetti immagine di pagina e di query supportano trasformazioni concatenate:
{{ page.image.width(800) }}
{{ page.image.size(600, 400) }}
{{ page.image.size(600, 400).webp.url }}
{{ page.image.raw.url }}Nei loop:
{{#each page.images as="img"}}
<img src="{{ img.size(400, 300).webp.url }}" alt="{{ img.description }}">
{{/each}}Metodi sulle Collection
Gli helper comuni per le collection includono:
firstlastcounteq(n)slice(start, length)
Esempi:
{{ page.images.first.url }}
{{ page.images.count }}
{{ page.images.eq(2).url }}Accesso Dinamico ai Campi
I campi personalizzati della pagina possono essere accessi per nome:
{{ page.summary }}
{{ page.body }}
{{ page.headline }}
{{ page.field name="my_custom_field" }}Usa questo quando la superficie di rendering corrente dipende realmente dai dati a livello di pagina. Non usarlo per nascondere un contratto di campo Component debole.
URL Localizzati
Facet può esporre helper di URL localizzati per rendering multilingue consapevole della pagina:
{{ page.localUrl lang="fr" }}
{{ page.localUrl lang="default" }}user
user rappresenta il contesto dell'utente corrente.
Le proprietà comuni includono:
user.iduser.nameuser.titleuser.emailuser.displayNameuser.isLoggedinuser.isGuestuser.isSuperuseruser.language
Uso tipico:
{{#if user.isLoggedin}}
<span>Hello, {{ user.displayName }}!</span>
{{else}}
<a href="/login/">Log In</a>
{{/if}}pages
pages espone helper orientati alle query per output scalari o aggregati.
I pattern comuni includono:
pages.count selector="..."pages.first selector="..."pages.last selector="..."pages.titles selector="..." sep=", "pages.json selector="..."
Esempi:
<p>Total posts: {{ pages.count selector="template=blog-post" }}</p>
<p>Categories: {{ pages.titles selector="template=category" sep=", " }}</p>Usa {{#pages}} quando hai bisogno di un blocco loop. Usa gli helper inline pages.* per output scalari.
languages / lang
languages e lang espongono il sistema delle lingue.
Le proprietà comuni includono:
languages.countlanguages.currentlanguages.defaultlanguages.isMultiLanguagelanguages.alllanguages.{name}
Esempio:
{{#if languages.isMultiLanguage}}
Current language: {{ languages.current.title }}
{{/if}}All'interno di {{#languages}}, ogni elemento lingua espone comunemente:
lang.idlang.namelang.titlelang.isDefaultlang.isCurrentlang.urllang.httpUrllang.locale
site
site fornisce valori a livello di sito.
Le proprietà comuni includono:
site.namesite.urlsite.httpUrlsite.httpHostsite.localesite.yearsite.assetssite.templatessite.adminUrlsite.adminProfileUrlsite.adminLogoutUrl
L'accesso in stile impostazioni può essere disponibile:
{{ 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>Usa le impostazioni a livello di sito per valori globali stabili, non per contenuti che dovrebbero appartenere a una Variabile o a un oggetto gestito a livello di pagina.
now
now fornisce valori temporali correnti.
Le proprietà comuni includono:
now.timestampnow.datenow.datetimenow.yearnow.monthnow.day
Esempio:
<footer>© {{ now.year }} {{ site.name }}</footer>attr
attr espone i valori passati in una Variabile:
{{! Usage: [[my-widget title="Hello" color="blue"]] }}
<div style="color: {{ attr.color | default("black") }}">
<h3>{{ attr.title | default("Default Title") }}</h3>
</div>attr dovrebbe rimanere piccolo e esplicito. Se un frammento necessita di un grande modello dati modificabile, probabilmente serve un Component invece di una Variabile.
loop
loop è disponibile all'interno di blocchi loop come:
{{#each}}{{#pages}}{{#languages}}
Proprietà comuni:
loop.indexloop.index1loop.firstloop.lastloop.lengthloop.evenloop.odd
Esempio:
{{#each page.children as="child"}}
<div class="{{#if loop.odd}}row-alt{{/if}}">
{{ loop.index1 }}. {{ child.title }}
</div>
{{/each}}this
All'interno di {{#each}}, this è l'elemento corrente del loop:
{{#each page.children}}
<a href="{{ this.url }}">{{ this.title }}</a>
{{/each}}this e un alias nominato normalmente puntano allo stesso elemento corrente.
@index
@index è scorciatoia per loop.index.
Esempio:
{{#each page.children as="child"}}
{{#if @index == 0}}
<h2>{{ child.title }}</h2>
{{else}}
<p>{{ child.title }}</p>
{{/if}}
{{/each}}Campi Root-Level del Component
Nei template Component, i campi dell'istanza del Component corrente sono spesso iniettati come variabili di root-level:
<h1>{{ title }}</h1>
{{#if showGallery}}
<div class="gallery">
{{#each images as="img"}}
<img src="{{ img.url }}">
{{/each}}
</div>
{{/if}}Questa è una delle ragioni per cui i template Component risultano più semplici rispetto ai template generici a livello di pagina.
I nomi riservati non dovrebbero essere riutilizzati a casaccio come nomi di campo personalizzati se entrano in conflitto con oggetti di contesto core come:
pagepagesuserlanguageslangsitenowattrloopthis@index
Riferimento degli Helper dei Campi Component
Facet lavora con diversi contratti helper specifici per i Component che non sono gli stessi dell'output generale {{ expr }}.
Helper per Campo Immagine Singola
I campi image singoli supportano comunemente:
{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}
Esempio:
<img src="{hero.width(1200).webp}" alt="{hero.description}">
<a href="{photo.raw}" download>Download original</a>Helper per Campi Multi-immagine
All'interno di {{#each gallery}}, gli elementi images supportano comunemente:
{{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}}
Esempio:
{{#each gallery}}
<figure>
<img src="{{this.width(600).webp}}" alt="{{this.description}}">
<figcaption>{{this.name}}</figcaption>
</figure>
{{/each}}Helper per Campo Mappa
I campi map supportano comunemente:
{field}{field.width(N)}{field.height(N)}{field.size(W,H)}
Esempi:
{officeLocation}
{officeLocation.width(600)}
{officeLocation.size(800,500)}Usa map solo per dati di localizzazione strutturati, non per testo di indirizzo semplice.
Contratti di Embed Gestiti
Gli embed nei workflow gestiti tipicamente usano:
data-form-embeddata-review-embed
Esempi:
<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>Usa id fissi per i workflow posseduti dal template e valori basati su campo per i workflow selezionabili dall'autore.
Riferimento dei Filtri
I filtri trasformano i valori prima dell'output. La regola più importante è semplice:
- usa i filtri per la formattazione
- non usare i filtri per nascondere un modello di oggetti debole
Filtri per Stringhe
I filtri comuni per stringhe includono:
escape/erawupperlowercapitalizetrimtruncatenl2brstriptagsreplacesplitslicepadwrapslug
Esempi:
{{ page.title | upper }}
{{ page.body | striptags | truncate(200, "...") }}
{{ text | nl2br }}
{{ title | slug }}Filtro Valore Predefinito
default fornisce un fallback quando l'input è mancante o nullo nel contratto supportato:
{{ page.subtitle | default("Untitled") }}Se il comportamento esatto della stringa vuota è importante, preferisci un ternario esplicito.
Filtri Numerici
I filtri numerici comuni includono:
numbercurrencyabsroundceilfloor
Esempi:
{{ 1234567 | number(0, ".", ",") }}
{{ price | currency("$", 2) }}
{{ ratio | round(2) }}Filtri Data
I filtri data comuni includono:
datedatetimerelative
Esempi:
{{ page.created | date("F j, Y") }}
{{ page.modified | datetime("Y-m-d H:i") }}
{{ page.modified | relative }}Filtri URL
I filtri orientati agli URL comuni includono:
url_encodeurl
Esempi:
{{ page.title | url_encode }}
{{ website | url }}Filtro JSON
Usa json per output JSON sicuro:
{{ data | json }}Questo è utile quando il template ha bisogno di dati strutturati in output HTML o script.
Filtri per Array e Collection
I filtri comuni per le collection includono:
joinfirstlastcountlengthreversesortpluckuniquebatchkeysvaluesmerge
Esempi:
{{ tags | pluck("title") | join(", ") }}
{{ page.children | count }}
{{ items | batch(4) }}Filtro Immagine
Filtro immagine comune:
size
Esempio:
{{ page.image | size(600, 400) }}Filtro Hash
Filtro hash comune:
md5
Esempio:
{{ user.email | md5 }}Sistema di Variabili
Le Variabili sono frammenti di template riutilizzabili che possono essere incorporati ovunque sia supportato dal rendering di FaceFlow.
Inclusione di Variabili
Inclusione base:
[[my-variable]]Con attributi:
[[my-widget title="Hello World" color="blue" count="5"]]Struttura di una Variabile
Una Variabile tipicamente contiene:
- template HTML
- CSS opzionale
- JS opzionale
- attributi opzionali
- modalità di cache
Modalità di Cache
Le modalità comuni includono:
staticdynamicauto
Usa:
staticquando l'output è generalmente adatto alla cachedynamicquando l'output dipende dallo stato runtime sensibile all'utente o alla richiestaautoquando il motore dovrebbe scegliere in base al comportamento della Variabile
Variabili Nidificate
Le Variabili possono includere altre Variabili:
<footer>
[[copyright-notice year="2026"]]
[[social-links]]
</footer>Usa il nesting per migliorare il riuso e la chiarezza, non per creare catene di dipendenza nascoste e profonde.
Sintassi a Livello di Layout
I template orientati al layout spesso si basano su alcuni segnaposto strutturali:
{content}{header}{footer}{siteComponents}
Esempio:
<body>
{header}
{siteComponents}
<main>
{content}
</main>
{footer}
</body>Questi segnaposto appartengono alla composizione del layout e della shell, non al rendering ordinario delle sezioni.
Attributi Dati
Gli attributi dati runtime comuni includono:
data-form-embeddata-review-embeddata-fb-mapdata-fb-map-fielddata-component-*data-form-ajaxdata-variabledata-loading
Usa questi quando il contratto runtime li documenta esplicitamente. Non inventare attributi paralleli a casaccio.
Riferimenti ai Media
Alcuni contesti di rendering FaceFlow possono esporre pattern di riferimento ai media gestiti come:
@image:filename@file:filename
Queste sono rappresentazioni lato implementazione di asset gestiti. Nei template redatti, preferisci gli helper documentati o le forme di output oggetto piuttosto che fare affidamento su riferimenti di storage grezzi.
Pipeline di Rendering
Un ordine pratico di rendering Facet solitamente appare così:
- load the owning FaceFlow object
- resolve the current render context
- inject root-level fields and context objects
- evaluate field helper contracts
- evaluate Facet expressions and block helpers
- resolve Variable embeds
- resolve managed runtime markers such as Forms, Reviews, or maps
- return final output
La lezione di design importante è che lo shorthand dei campi Component, le espressioni Facet, gli embed di Variabili e i marker runtime gestiti sono fasi correlate ma non identiche.
Modello di Sicurezza
Facet è progettato come un livello di template governato piuttosto che un ambiente di esecuzione di codice grezzo.
Regole chiave:
- nessuna esecuzione arbitraria di codice server-side
- gli oggetti root sono controllati
- filtri e tipi di blocco sono in whitelist
- il comportamento delle query è vincolato
- l'output raw dovrebbe essere usato intenzionalmente
Considera questo come un linguaggio di template sandboxed, non come un motore di scripting di riserva.
Regole di Design Pratiche
- preferisci confini oggetto chiari rispetto a logiche di template sofisticate
- mantieni la logica del template superficiale
- usa Variabili per frammenti e Component per contratti di sezione
- usa Liste quando query e paginazione fanno parte del contratto
- verifica qualsiasi sintassi helper di campo contro il riferimento del campo prima di usarla
- rivedi i contenuti sensibili alla cache prima di introdurre rendering differito
Modelli Pratici
Menu di Navigazione
<nav>
<ul>
{{#pages selector="parent=1, sort=sort" as="item"}}
<li><a href="{{ item.url }}">{{ item.title }}</a></li>
{{/pages}}
</ul>
</nav>Elenco Post del Blog
{{#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}}Selettore Multilingua
{{#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>Benvenuto Utente Sicuro per la Cache
{{#deferred skeleton-width="10rem" skeleton-height="2rem"}}
{{#if user.isLoggedin}}
<span>{{ user.displayName }}</span>
{{else}}
<a href="/login/">Sign In</a>
{{/if}}
{{/deferred}}Domande Frequenti
Quando dovrei usare {{#pages}} vs {{#each}}?
- usa
{{#each}}quando i dati esistono già nel contesto corrente - usa
{{#pages}}quando il template deve interrogare i dati
Qual è la differenza tra {{ }} e {{{ }}}?
{{ ... }}è output escaped{{{ ... }}}è output raw
Usa l'output escaped per default.
Posso annidare loop?
Sì, ma solo quando il modello di oggetti rimane leggibile. Se i loop annidati compensano un contratto di contenuto debole, fermati e rivedi il design.
Perché un campo ritorna null o output vuoto?
Cause comuni:
- contesto sbagliato
- nome del campo sbagliato
- utilizzo della famiglia di sintassi sbagliata per l'oggetto corrente
- aspettarsi un helper su un campo che non lo supporta
Come dovrei fare il debug dei problemi di template?
Inizia in questo ordine:
- conferma il contratto dell'oggetto proprietario
- conferma la famiglia di sintassi corretta
- conferma gli oggetti di contesto disponibili
- riduci il template al frammento riproducibile più piccolo
- quindi ricostruisci da lì