Referência do Facet
Referência do Facet
Use esta página quando o guia de sintaxe primário não for mais suficiente e você precisar de material de referência mais aprofundado sobre o comportamento do Facet, objetos de contexto, contratos de helpers e regras de renderização.
Esta página é propositalmente densa. É o companheiro de referência técnica para:
O que esta página cobre
Use esta referência quando precisar de detalhes sobre:
- objetos de contexto e suas propriedades comuns
- padrões de acesso a página, mídia e coleções
- contratos de helpers de imagem e mapa
- filtros por categoria
- comportamento do sistema de Variáveis
- slots em nível de layout
- atributos de dados gerenciados
- referências de mídia
- regras de renderização e segurança
Objetos de contexto
Templates do Facet têm acesso a um conjunto controlado de objetos de nível raiz. Quais propriedades são úteis depende da superfície de render atual, mas o mesmo modelo mental se aplica em todo lugar.
page
page é o objeto de página atual no contexto de renderização atual.
Propriedades principais da página
Propriedades escalares comuns incluem:
page.idpage.namepage.titlepage.urlpage.httpUrlpage.pathpage.templatepage.createdpage.modifiedpage.createdStrpage.modifiedStrpage.statuspage.sortpage.numChildren
Uso típico:
<h1>{{ page.title }}</h1>
<p>Updated {{ page.modified | date("F j, Y") }}</p>Propriedades do tipo status
Propriedades booleanas comuns incluem:
page.isPublishedpage.isHiddenpage.isUnpublishedpage.isTrashpage.isNewpage.hasChildrenpage.isEditable
Exemplo:
{{#if page.hasChildren}}
<p>This page has child pages.</p>
{{/if}}page.isEditable é especialmente útil para interfaces que devem aparecer apenas para os editores da página atual:
{{#if page.isEditable}}
<a href="{{ page.url }}?edit=1">Edit this page</a>
{{/if}}Propriedades relacionais
Facet normalmente expõe acesso relacional como:
page.parentpage.parentspage.rootParentpage.childrenpage.siblingspage.nextpage.prevpage.find
Exemplos:
{{ page.parent.title }}
{{ page.rootParent.title }}
{{#each page.children as="child"}}
<a href="{{ child.url }}">{{ child.title }}</a>
{{/each}}Propriedades de mídia
Propriedades orientadas a mídia comuns incluem:
page.imagespage.imagepage.files
Exemplos:
{{#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}}Propriedades de objeto de imagem
Propriedades típicas de um objeto de imagem incluem:
img.urlimg.httpUrlimg.filenameimg.descriptionimg.widthimg.heightimg.extimg.filesizeimg.webp.urlimg.raw.url
Propriedades de objeto de arquivo
Propriedades típicas de um objeto de arquivo incluem:
file.urlfile.httpUrlfile.filenamefile.descriptionfile.extfile.filesize
Transformações de imagem
Objetos de imagem de página e de consulta suportam transforms encadeados:
{{ page.image.width(800) }}
{{ page.image.size(600, 400) }}
{{ page.image.size(600, 400).webp.url }}
{{ page.image.raw.url }}Em loops:
{{#each page.images as="img"}}
<img src="{{ img.size(400, 300).webp.url }}" alt="{{ img.description }}">
{{/each}}Métodos de coleção
Helpers comuns de coleção incluem:
firstlastcounteq(n)slice(start, length)
Exemplos:
{{ page.images.first.url }}
{{ page.images.count }}
{{ page.images.eq(2).url }}Acesso dinâmico a campos
Campos personalizados da página podem ser acessados por nome:
{{ page.summary }}
{{ page.body }}
{{ page.headline }}
{{ page.field name="my_custom_field" }}Use isto quando a superfície de render atual realmente depende de dados em nível de página. Não use isso para ocultar um contrato fraco de campo de Component.
URL localizado
Facet pode expor helpers de URL localizados para renderização multilíngue sensível à página:
{{ page.localUrl lang="fr" }}
{{ page.localUrl lang="default" }}user
user representa o contexto do usuário atual.
Propriedades comuns incluem:
user.iduser.nameuser.titleuser.emailuser.displayNameuser.isLoggedinuser.isGuestuser.isSuperuseruser.language
Uso típico:
{{#if user.isLoggedin}}
<span>Hello, {{ user.displayName }}!</span>
{{else}}
<a href="/login/">Log In</a>
{{/if}}pages
pages expõe helpers orientados a consulta para saídas escalares ou agregadas.
Padrões comuns incluem:
pages.count selector="..."pages.first selector="..."pages.last selector="..."pages.titles selector="..." sep=", "pages.json selector="..."
Exemplos:
<p>Total posts: {{ pages.count selector="template=blog-post" }}</p>
<p>Categories: {{ pages.titles selector="template=category" sep=", " }}</p>Use {{#pages}} quando precisar de um bloco de loop. Use helpers inline pages.* para saídas escalares.
languages / lang
languages e lang expõem o sistema de idiomas.
Propriedades comuns incluem:
languages.countlanguages.currentlanguages.defaultlanguages.isMultiLanguagelanguages.alllanguages.{name}
Exemplo:
{{#if languages.isMultiLanguage}}
Current language: {{ languages.current.title }}
{{/if}}Dentro de {{#languages}}, cada item de idioma normalmente expõe:
lang.idlang.namelang.titlelang.isDefaultlang.isCurrentlang.urllang.httpUrllang.locale
site
site fornece valores em nível de site.
Propriedades comuns incluem:
site.namesite.urlsite.httpUrlsite.httpHostsite.localesite.yearsite.assetssite.templatessite.adminUrlsite.adminProfileUrlsite.adminLogoutUrl
Acesso no estilo de configurações também pode estar disponível:
{{ 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>Use configurações em nível de site para valores globais estáveis, não para conteúdo que deveria pertencer a uma Variable ou a um objeto gerenciado em nível de página.
now
now fornece valores de tempo atuais.
Propriedades comuns incluem:
now.timestampnow.datenow.datetimenow.yearnow.monthnow.day
Exemplo:
<footer>© {{ now.year }} {{ site.name }}</footer>attr
attr expõe valores passados para uma Variable:
{{! Usage: [[my-widget title="Hello" color="blue"]] }}
<div style="color: {{ attr.color | default("black") }}">
<h3>{{ attr.title | default("Default Title") }}</h3>
</div>attr deve permanecer pequeno e explícito. Se um fragmento precisa de um grande modelo de dados editável, provavelmente ele quer um Component em vez de uma Variable.
loop
loop está disponível dentro de blocos de loop como:
{{#each}}{{#pages}}{{#languages}}
Propriedades comuns:
loop.indexloop.index1loop.firstloop.lastloop.lengthloop.evenloop.odd
Exemplo:
{{#each page.children as="child"}}
<div class="{{#if loop.odd}}row-alt{{/if}}">
{{ loop.index1 }}. {{ child.title }}
</div>
{{/each}}this
Dentro de {{#each}}, this é o item atual do loop:
{{#each page.children}}
<a href="{{ this.url }}">{{ this.title }}</a>
{{/each}}this e um alias nomeado normalmente apontam para o mesmo item atual.
@index
@index é atalho para loop.index.
Exemplo:
{{#each page.children as="child"}}
{{#if @index == 0}}
<h2>{{ child.title }}</h2>
{{else}}
<p>{{ child.title }}</p>
{{/if}}
{{/each}}Campos do componente no nível raiz
Em templates de Component, os campos da instância do Component atual frequentemente são injetados como variáveis de nível raiz:
<h1>{{ title }}</h1>
{{#if showGallery}}
<div class="gallery">
{{#each images as="img"}}
<img src="{{ img.url }}">
{{/each}}
</div>
{{/if}}Esta é uma das razões pelas quais templates de Component parecem mais simples que templates genéricos em nível de página.
Nomes reservados não devem ser reutilizados casualmente como nomes de campo personalizados se eles colidirem com objetos de contexto principais tais como:
pagepagesuserlanguageslangsitenowattrloopthis@index
Referência de helpers de campo de Component
Facet funciona com vários contratos de helper específicos de Component que não são os mesmos que a saída geral {{ expr }}.
Helpers de campo de imagem única
Campos image únicos comumente suportam:
{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}
Exemplo:
<img src="{hero.width(1200).webp}" alt="{hero.description}">
<a href="{photo.raw}" download>Download original</a>Helpers de campo de múltiplas imagens
Dentro de {{#each gallery}}, itens images comumente suportam:
{{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}}
Exemplo:
{{#each gallery}}
<figure>
<img src="{{this.width(600).webp}}" alt="{{this.description}}">
<figcaption>{{this.name}}</figcaption>
</figure>
{{/each}}Helpers de campo de mapa
Campos map comumente suportam:
{field}{field.width(N)}{field.height(N)}{field.size(W,H)}
Exemplos:
{officeLocation}
{officeLocation.width(600)}
{officeLocation.size(800,500)}Use map apenas para dados estruturados de localização, não para cópia de endereço simples.
Contratos de embed gerenciados
Embeds em fluxo de trabalho gerenciado tipicamente usam:
data-form-embeddata-review-embed
Exemplos:
<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>Use ids fixos para fluxos de trabalho possuídos por template e valores baseados em campo para fluxos de trabalho selecionáveis pelo autor.
Referência de filtros
Filtros transformam valores antes da saída. A regra mais importante é simples:
- use filtros para formatação
- não use filtros para ocultar um modelo de objeto fraco
Filtros de string
Filtros de string comuns incluem:
escape/erawupperlowercapitalizetrimtruncatenl2brstriptagsreplacesplitslicepadwrapslug
Exemplos:
{{ page.title | upper }}
{{ page.body | striptags | truncate(200, "...") }}
{{ text | nl2br }}
{{ title | slug }}Filtro de valor padrão
default fornece um fallback quando a entrada está ausente ou é nula na contract suportada:
{{ page.subtitle | default("Untitled") }}Se o comportamento exato de string vazia for importante, prefira um ternário explícito.
Filtros numéricos
Filtros numéricos comuns incluem:
numbercurrencyabsroundceilfloor
Exemplos:
{{ 1234567 | number(0, ".", ",") }}
{{ price | currency("$", 2) }}
{{ ratio | round(2) }}Filtros de data
Filtros de data comuns incluem:
datedatetimerelative
Exemplos:
{{ page.created | date("F j, Y") }}
{{ page.modified | datetime("Y-m-d H:i") }}
{{ page.modified | relative }}Filtros de URL
Filtros orientados a URL comuns incluem:
url_encodeurl
Exemplos:
{{ page.title | url_encode }}
{{ website | url }}Filtro JSON
Use json para saída JSON segura:
{{ data | json }}Isto é útil quando o template precisa de dados estruturados em HTML ou saída orientada a script.
Filtros de array e coleção
Filtros de coleção comuns incluem:
joinfirstlastcountlengthreversesortpluckuniquebatchkeysvaluesmerge
Exemplos:
{{ tags | pluck("title") | join(", ") }}
{{ page.children | count }}
{{ items | batch(4) }}Filtro de imagem
Filtro de imagem comum:
size
Exemplo:
{{ page.image | size(600, 400) }}Filtro de hash
Filtro de hash comum:
md5
Exemplo:
{{ user.email | md5 }}Sistema de Variáveis
Variables são fragmentos de template reutilizáveis que podem ser incorporados em qualquer lugar suportado pela renderização FaceFlow.
Inclusão de Variables
Inclusão básica:
[[my-variable]]Com atributos:
[[my-widget title="Hello World" color="blue" count="5"]]Estrutura de uma Variable
Uma Variable tipicamente contém:
- template HTML
- CSS opcional
- JS opcional
- atributos opcionais
- modo de cache
Modos de cache
Modos comuns incluem:
staticdynamicauto
Use:
staticquando a saída for amplamente compatível com cachedynamicquando a saída depender de estado em tempo de execução sensível ao usuário ou à requisiçãoautoquando o mecanismo deve escolher com base no comportamento da Variable
Variables aninhadas
Variables podem incluir outras Variables:
<footer>
[[copyright-notice year="2026"]]
[[social-links]]
</footer>Use aninhamento para melhorar a reutilização e clareza, não para criar cadeias profundas de dependências ocultas.
Sintaxe de nível de layout
Templates orientados a layout frequentemente dependem de alguns placeholders estruturais:
{content}{header}{footer}{siteComponents}
Exemplo:
<body>
{header}
{siteComponents}
<main>
{content}
</main>
{footer}
</body>Esses placeholders pertencem à composição de layout e shell, não à renderização de seções ordinárias.
Atributos de dados
Atributos de dados orientados a runtime comuns incluem:
data-form-embeddata-review-embeddata-fb-mapdata-fb-map-fielddata-component-*data-form-ajaxdata-variabledata-loading
Use estes quando o contrato de runtime os documentar explicitamente. Não invente atributos paralelos casualmente.
Referências de mídia
Alguns contextos de renderização FaceFlow podem expor padrões de referência de mídia gerenciada tais como:
@image:filename@file:filename
Estas são representações do lado de implementação de ativos gerenciados. Em templates autorais, prefira o helper documentado ou as formas de saída de objeto em vez de confiar em referências brutas de armazenamento.
Pipeline de renderização
Uma ordem prática de renderização do Facet geralmente se parece com isto:
- 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
A lição de design importante é que o atalho de campo de Component, expressões Facet, embeds de Variable e marcadores de runtime gerenciados são estágios relacionados, mas não idênticos.
Modelo de segurança
Facet é projetado como uma camada de templates governada em vez de um ambiente de execução de código bruto no servidor.
Regras chave:
- sem execução arbitrária de código do lado servidor
- objetos raiz são controlados
- filtros e tipos de bloco são permitidos por whitelist
- comportamento de consulta é restrito
- saída raw deve ser usada intencionalmente
Trate isto como uma linguagem de template sandboxed, não como um mecanismo de script de fallback.
Regras práticas de design
- prefira limites claros de objeto em vez de lógica esperta no template
- mantenha a lógica do template rasa
- use Variables para fragmentos e Components para contratos de seção
- use Lists quando consulta e paginação fizerem parte do contrato
- revise qualquer sintaxe de helper de campo contra a referência de campo antes de usá-la
- revise conteúdo sensível ao cache antes de introduzir renderização adiada
Padrões (Cookbook)
Menu de navegação
<nav>
<ul>
{{#pages selector="parent=1, sort=sort" as="item"}}
<li><a href="{{ item.url }}">{{ item.title }}</a></li>
{{/pages}}
</ul>
</nav>Lista de posts do 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}}Alternador multilíngue
{{#if languages.isMultiLanguage}}
{{#languages as="lang"}}
<a href="{{ lang.url }}">{{ lang.title }}</a>
{{/languages}}
{{/if}}Trilha de navegação (Breadcrumbs)
{{#each page.parents as="p"}}
<a href="{{ p.url }}">{{ p.title }}</a> /
{{/each}}
<span>{{ page.title }}</span>Saudação ao usuário segura para cache
{{#deferred skeleton-width="10rem" skeleton-height="2rem"}}
{{#if user.isLoggedin}}
<span>{{ user.displayName }}</span>
{{else}}
<a href="/login/">Sign In</a>
{{/if}}
{{/deferred}}Perguntas frequentes
Quando devo usar {{#pages}} vs {{#each}}?
- use
{{#each}}quando os dados já existirem no contexto atual - use
{{#pages}}quando o template deve consultar os dados
Qual a diferença entre {{ }} e {{{ }}}?
{{ ... }}é saída escapada{{{ ... }}}é saída raw
Use saída escapada por padrão.
Posso aninhar loops?
Sim, mas apenas quando o modelo de objeto permanecer legível. Se loops aninhados estiverem compensando um contrato de conteúdo fraco, pare e revise o design.
Por que um campo retorna null ou saída vazia?
Causas comuns:
- contexto errado
- nome de campo incorreto
- usando a família de sintaxe errada para o objeto atual
- esperando um helper em um campo que não o suporta
Como devo depurar problemas de template?
Comece nesta ordem:
- confirm the owning object contract
- confirm the right syntax family
- confirm the available context objects
- reduce the template to the smallest reproducible fragment
- then rebuild from there