Frammenti di contenuto visivo - Modelli visual-content-fragments-templates
In Adobe Experience Manager (AEM) as a Cloud Service, è possibile utilizzare i modelli HTML per visualizzare i frammenti di contenuto e distribuirli in formato HTML.
I modelli di HTML consentono di controllare la modalità di visualizzazione dei frammenti di contenuto. Puoi creare modelli HTML nell’editor di codice desiderato, quindi caricarli e assegnarli a Modelli per frammenti di contenuto in AEM. I segnaposto di contenuto che utilizzano Handlebars.js consentono di mappare il modello ai tipi di dati nel modello per frammenti di contenuto. Una volta assegnato a un modello, un modello è disponibile per essere utilizzato con qualsiasi frammento di contenuto basato sul modello, per visualizzare il frammento o per distribuirlo come esperienza modulare in formato HTML a qualsiasi canale, ad esempio web, e-mail, app mobile o altri.
Questo articolo spiega come creare modelli HTML personalizzati con sintassi Handlebars per il rendering dei frammenti di contenuto visivo.
Dopo aver creato i modelli puoi:
Cosa imparerai what-you-will-learn
Dopo aver fornito un’introduzione (molto rapida) a:
- Come utilizzare i modelli in AEM
- Utilizzo dell’URL di pubblicazione
In questa pagina vengono descritti (più dettagliatamente):
- Handlebars: nozioni di base sulla sintassi
- Come accedere ai dati dei frammenti di contenuto
- Utilizzo di frammenti di contenuto nidificati
- Gestione di campi con più valori
- Creazione di loop e logica condizionale
- Best practice per la progettazione di modelli per frammenti di contenuto
Prerequisiti prerequisites
Per comprendere e utilizzare le tecnologie qui descritte, è necessario disporre di:
- Nozioni di base su HTML
- Familiarità con i frammenti di contenuto e i modelli per frammenti di contenuto di AEM
- Informazioni sui modelli per frammenti di contenuto
Utilizzo di un modello HTML per frammenti di contenuto using-a-content-fragment-html-template
Utilizzo di un modello HTML per frammenti di contenuto in AEM using-a-content-fragment-html-template-in-aem
Per informazioni dettagliate su come utilizzare il modello in AEM, consulta:
Utilizzo dell’URL di pubblicazione del frammento di contenuto visivo using-the-visual-content-fragment-publish-url
Dopo aver creato i frammenti di contenuto visivo utilizzando il modello, puoi utilizzare l’URL di pubblicazione dei frammenti di contenuto visivo.
Handlebars - the (very) basics handlebars-the-very-basics
Handlebars è un linguaggio di modelli semplice che utilizza parentesi graffe doppie {{ }} per inserire contenuto dinamico in HTML.
Sintassi di base basic-syntax
Un esempio di sintassi di base di Handlebars:
Concetti fondamentali key-concepts
I concetti chiave di Handlebars:
{{ }}{{{ }}}{{! }}{{{ }}}) per i valori dei campi perché i valori sono HTML di cui è stato eseguito il rendering anticipato.Riferimento contesto modello template-context-reference
Quando viene eseguito il rendering del modello, questo riceve un oggetto contestuale contenente tutti i dati sul frammento di contenuto. Ciò riguarderà:
-
frammento selezionato
-
tutti gli altri frammenti a cui si fa riferimento dal frammento selezionato
note NOTE È possibile fare riferimento ai frammenti: - nell’interfaccia utente: fino alla profondità massima di 5
- quando si utilizza l’API: la profondità è configurabile, fino alla profondità massima di 10
Frammento di contenuto principale main-content-fragment
Struttura dell’oggetto contestuale per il frammento di contenuto (selezionato):
fieldsallFields{name, value} per l’iterazionehasFieldstrue se il frammento ha campimetadataStruttura delle proprietà (frammenti principali e di riferimento) properties-structure-main-and-referenced-fragments
L’oggetto properties ha la stessa struttura per il frammento selezionato e per ogni frammento di riferimento.
idtitledescriptionpath/content/dam/...hasDescriptiontruecreatedDatemodifiedDatepublishedDatestatusDRAFTmodelid, path, name, technicalName, descriptionvalidationStatus{property, message}previewReplicationStatustagsid, title, titlePath, name, path, descriptionfieldTagstags.Esempi: accesso ai modelli
Per il frammento di contenuto (selezionato):
Frammenti di contenuto di riferimento referenced-content-fragments
Struttura dell’oggetto contestuale per tutti i frammenti a cui si fa riferimento:
hasReferencedFragmentstrue quando esistono riferimentireferencedFragmentsreferencesErrortrue se si è verificato un errore durante il caricamento dei riferimentireferencesErrorMessagereferencesError è trueStruttura dei frammenti di riferimento referenced-fragment-structure
Ogni elemento in referencedFragments contiene:
anchorIdpropertieshasFieldsfieldsallFields{name, value} per l’iterazionemetadataEsempi: accesso al modello per il primo frammento di contenuto a cui si fa riferimento (primo elemento nell’elenco con indice 0):
Oppure dalla mappa dei campi:
Struttura dei metadati per frammenti di contenuto content-fragment-metadata-structure
I metadati di un frammento, ovvero il blocco metadati/campi supportato dal relativo schema metadati, vengono visualizzati in metadata. È diverso da properties, che contiene i valori strutturali (title, description, path, tags, dates, status).
metadatametadata espressioni risultano vuote anziché erratemetadata.schemaIddefault quando non ne viene trovato alcunometadata.valuesmetadata.fieldsname, type (stringa, numero intero, numero, booleano, array, oggetto), value e title (etichetta leggibile dallo schema)metadata.values mantiene i tipi JSON, un numero o un valore booleano letto da questo valore funziona direttamente con il confronto e gli helper booleani, a differenza di un campo scalare che raggiunge il modello pre-renderizzato come stringa. Vedi anche Helper per confronto e logica booleana.Struttura dei campi della risorsa asset-field-structure
Le risorse a cui si fa riferimento non sono una raccolta di primo livello; non esiste referencedAssets. Una risorsa viene raggiunta tramite il campo che la contiene, fields.<assetField> o fields.<ref>.fields.<assetField>, per una risorsa all’interno di un frammento di riferimento.
Il valore di un campo cespite è a doppia natura. Stampato non elaborato, è la risorsa di cui è stato eseguito il pre-rendering in HTML. Eseguito il drilling in, espone i metadati della risorsa in properties.
<img> per un’immagine).Richiede parentesi graffe:
{{{fields.heroImage}}}propertiesUn campo risorsa con più valori è un elenco. Eseguire l’iterazione con {{#each fields.gallery}}, utilizzando {{{this}}} per HTML e {{this.properties.assetId}} per i metadati.
Proprietà di una risorsa DAM locale properties-of-a-local-dam-asset
Queste chiavi sono gestite dalla risposta Frammento di contenuto e sono sempre disponibili:
assetIdurn:aaid:aem:1fb05fe4-...path/content/dam/wknd/ian_provo.jpgnameian_provo.jpgtitledescriptiontypeassetassetfieldNameprofilePicturestatusNEW, DRAFT, PUBLISHED, MODIFIED, UNPUBLISHEDDRAFTpreviewReplicationStatusPUBLISHED, UNPUBLISHED, MODIFIED, NEVER_PUBLISHEDcreated, modified, publishedat (ISO-8601), by, fullName, firstName, lastNamedc:formatimage/jpegrepo:size251434tiff:ImageWidth1152tiff:ImageHeight1152yournamespace:persistentID. Recuperato dalla risorsa su richiestaI nomi di proprietà che contengono due punti richiedono la sintassi tra parentesi:
Proprietà di una risorsa Dynamic Media properties-of-a-dynamic-media-asset
Una risorsa Dynamic Media (remota) non dispone di un percorso DAM. Solo due chiavi sono in linea:
repositorydelivery-p12345-e67890.adobeaemcloud.comassetIdurn:aaid:aem:1fb05fe4-...Insieme, questi sono sufficienti per creare un URL di consegna Dynamic Media invece di utilizzare l’immagine incorporata. Ogni altra proprietà viene recuperata dall’host di consegna della risorsa. Solo le risorse approvate (pubblicate) vengono servite, quindi una risorsa Dynamic Media non approvata non risolve nulla oltre queste due chiavi.
this.properties.<key> e non un bare properties.<key>. Un percorso vuoto la cui chiave è anche una proprietà del frammento di contenuto, come title, description, path o status, viene risolto rispetto al frammento e non alla risorsa.Accesso ai campi di base basic-field-access
Si consiglia l’accesso diretto ai campi, se necessario è possibile eseguire iterazioni in tutti i campi.
Accesso diretto al campo (consigliato) direct-field-access-recommended
Accedi direttamente ai campi per nome utilizzando la mappa dei campi:
Ricorda:
- Usa parentesi graffe
{{{ }}}per i valori di campo se contengono HTML (Rich Text) pre-renderizzati - I nomi dei campi (titolo, sottotitolo, descrizione, immagine primaria) devono corrispondere esattamente al modello per frammenti di contenuto
- I campi mancanti non vengono visualizzati: non vengono generati errori e la sintassi Handlebars rimane presente (e visibile) nel frammento HTML renderizzato
Scorre tutti i campi iterate-through-all-fields
Utilizza allFields quando non conosci in anticipo i nomi dei campi:
Ricorda:
{{name}}utilizza le parentesi graffe (etichetta testo normale){{{value}}}utilizza parentesi graffe (valore HTML pre-renderizzato)
Frammenti di contenuto nidificati nested-content-fragments
Quando un campo Frammento di contenuto fa riferimento a un altro frammento di contenuto, puoi utilizzare la notazione del punto per accedere direttamente ai campi nel frammento di riferimento.
Nidificazione a livello singolo single-level-nesting
Esempio di nidificazione a livello singolo:
Pattern: fields.referenceFieldName.nestedFieldName
Nidificazione a più livelli multi-level-nesting
Il sistema supporta una profondità di nidificazione illimitata:
Pattern: fields.level1.level2.level3.fieldName (profondità limitata; il valore predefinito è 5, può essere esteso a 10 quando si utilizza l’API)
Requisito parametro API: idratazione api-parameter-requirements
Per abilitare l’accesso ai frammenti di contenuto nidificati, è necessario includere il parametro di query hydration nella chiamata API:
Per attivare l’idratazione:
# Enable hydration with depth=2 for 2 levels of nesting
GET /adobe/sites/cf/fragments/{id}/preview?hydration=%7B%22enabled%22%3Atrue%2C%22maxDepth%22%3A2%7D
maxDepth123+Campi multivalore multi-valued-fields
Esistono diversi tipi di campi con più valori.
Campi di testo con più valori multi-valued-text-fields
Testo, numero, data e altri campi semplici diventano matrici se multivalore:
Quando si accede a elementi array per indice in Handlebars:
- Utilizza:
.[0](punto prima parentesi)
- Non:
[0]
Campi numerici multivalore multi-valued-number-fields
I numeri vengono convertiti in stringhe per il rendering:
Riferimenti a frammenti di contenuto con più valori multi-valued-content-fragment-references
Quando un campo fa riferimento a più frammenti di contenuto:
Riferimenti a risorse con più valori multi-valued-asset-references
I campi Riferimento contenuto configurati per i tipi di contenuto che sono risorse (ad esempio, immagini e documenti) vengono prerenderizzati come HTML. Le risorse multivalore diventano array:
Riferimenti con più valori nidificati nested-multi-valued-references
I riferimenti multivalore possono contenere riferimenti multivalore a qualsiasi profondità:
Cicli e iterazione loops-and-iteration
Handlebars fornisce l’helper {{#each}} per l’iterazione su array e oggetti.
Iterazione su array iterating-over-arrays
Esempio di iterazione su array:
Variabili speciali nei cicli special-variables-in-loops
All’interno di {{#each}} blocchi, Handlebars fornisce variabili speciali:
Iterazione su frammenti di riferimento iterating-over-referenced-fragments
Esempio di iterazione sui frammenti di riferimento:
Loop nidificati nested-loops
Esempio di loop nidificati:
Rendering condizionale conditional-rendering
Utilizza le condizionali per mostrare o nascondere il contenuto in base alla disponibilità dei dati.
If/Else di base basic-if-else
Esempio di costrutto di base if-else:
A meno che (condizionale negativo) unless-negative-conditional
Un helper unless:
hideAuthor è un valore booleano reale; ad esempio, da metadata.values.*. Tuttavia, un campo booleano con valore singolo arriva come stringa "true" o "false" e "false" è una stringa non vuota (truthy), quindi {{#unless fields.hideAuthor}} nasconde l'autore anche quando il campo è false. Confrontare invece esplicitamente il campo scalare, ad esempio {{#if (eq fields.hideAuthor "true")}}. Vedi anche Helper per confronto e logica booleana.Condizionali nidificati nested-conditials
Esempio di condizionale nidificato:
Helper per logica booleana e confronto comparison-and-boolean-logic-helpers
Oltre agli helper Stock {{#if}} e {{#unless}}, il servizio registra gli helper di confronto e logica booleana in modo che un modello possa eseguire il rendering in modo condizionale sui valori dei campi. Sia gli helper di confronto che quelli booleani-logici funzionano come un blocco e come una sottoespressione in linea:
Confronto numerico su campi con valore singolo numeric-comparison-on-single-valued-fields
Un campo con valore singolo arriva come stringa pre-sottoposta a rendering (fields.quantity is "7", non 7), ma gli helper forzano una stringa numerica al momento del confronto, quindi {{#gte fields.quantity 5}} e {{#eq fields.quantity 0}} vengono confrontati come numeri, insieme a {{#gte metadata.values.quantity 5}}, dove il valore è già stato digitato. L’ordinamento (gt/gte/lt/lte) confronta sempre numericamente. L’uguaglianza è coerente con l’intento: un campo stringa viene confrontato come numero solo quando l’altro operando è un numero autentico, un valore letterale numerico ({{#eq fields.qty 0}}) o un campo digitato come metadata.values.*. Il confronto tra due campi stringa o un valore letterale tra virgolette ({{#eq fields.version "1.0"}}) mantiene l’uguaglianza esatta tra stringhe, pertanto le versioni, i codici postali e gli ID modellati come testo non vengono mai compressi ("007" non è uguale a "7"). Le date attraversano il filo come stringhe ISO-8601, quindi eq/neq le confronta con l’uguaglianza esatta delle stringhe e gli helper per l’ordinamento le rifiutano come non numeriche. Un operando mancante, vuoto o non numerico viene considerato come “condizione non soddisfatta” ed esegue il rendering del ramo else anziché generare un errore.
Gli assistenti booleani utilizzano la veridicità semplice (nessuna coercizione) boolean-helpers-use-plain-truthiness-no-coercion
Gli helper booleani and/or/not non forzano. Applicano l’autenticità Handlebars stock, dove qualsiasi stringa non vuota è truthy (i valori falsy sono false, null, undefined, 0, "", []). Un campo booleano a valore singolo arriva come stringa "true" o "false" e "false" è una stringa non vuota, quindi {{#not fields.flag}} vede un valore truthy e prende il ramo else anche quando il campo legge false. Confrontare in modo esplicito un campo booleano scalare ({{#eq fields.flag "true"}}) anziché inviarlo a and/or/not; una lettura booleana da metadata.values.* è già stata digitata e funziona direttamente con gli helper booleani.
Campi denominati con un helper fields-named-after-a-helper
La registrazione di questi helper richiede i loro nomi a livello globale, ma un campo con il nome di uno genera ancora il proprio valore quando viene letto senza argomenti: {{eq}} all’interno di {{#with fields}} stampa il testo del campo eq, non un risultato di confronto. Gli helper sono disponibili sia nel modello di visualizzazione che all’interno di Handlebars incorporati in un valore di campo per frammenti di contenuto.
Helper Handlebars integrati built-in-handlebars-helpers
Handlebars include diversi helper incorporati, oltre a {{#if}} e {{#each}}.
{{#if condition}}false, undefined, null, 0, "", []{{#unless condition}}#if){{#each array}}{{else}} per gli array vuoti{{#with object}}{{lookup this "key"}}Con Helper with-helper
Crea un nuovo ambito per gli oggetti nidificati per ridurre i prefissi di percorso ripetitivi:
Modelli avanzati advanced-patterns
Seguono alcuni esempi di pattern avanzati.
Accesso al contesto padre nei loop nidificati accessing-parent-context-in-nested-loops
Utilizzare ../ per accedere all’ambito padre da un loop nidificato:
Classi CSS dinamiche dynamic-css-classes
Esempio di classi CSS dinamiche:
Esempi completi complete-examples
Sono forniti diversi esempi completi a titolo di riferimento.
Post di blog con autore
Un post di blog con i dettagli dell’autore:
Chiamata API richiesta:
GET /adobe/sites/cf/fragments/{id}/preview?hydration=%7B%22enabled%22%3Atrue%2C%22maxDepth%22%3A1%7D
Vista tabella generica (nessuna conoscenza precedente dei campi) generic-table-view-no-prior-knowledge-of-fields
Visualizzazione tabella generica, senza una conoscenza dei campi. È simile al modello generico:
Best practice best-practices
Le best practice includono:
-
Utilizza sempre parentesi graffe triple per i valori dei campi che contengono contenuto di markup HTML.
-
I valori dei campi sono HTML di cui è stato eseguito il pre-rendering.
note NOTE Le doppie parentesi graffe mostrano i tag HTML non elaborati come testo normale.
code language-handlebars <!-- CORRECT --> {{{fields.description}}} <!-- WRONG - displays HTML tags as text --> {{fields.description}} -
-
Verifica la presenza prima di accedere ai campi nidificati.
code language-handlebars <!-- GOOD: check before accessing nested fields --> {{#if fields.author}} <p>By {{{fields.author.name}}}</p> {{/if}} <!-- RISKY: may render empty if author is not set --> <p>By {{{fields.author.name}}}</p> -
Se possibile, utilizza l’accesso diretto ai campi.
- È più leggibile e gestibile rispetto all’iterazione di
allFieldse alla corrispondenza per nome.
- È più leggibile e gestibile rispetto all’iterazione di
-
Modelli di struttura con commenti di sezione.
code language-handlebars {{! ===== HEADER SECTION ===== }} <header> <h1>{{properties.title}}</h1> </header> {{! ===== MAIN CONTENT ===== }} <main> {{#if hasFields}} <!-- fields rendering --> {{/if}} </main> {{! ===== REFERENCES ===== }} {{#if hasReferencedFragments}} <!-- references rendering --> {{/if}} -
Gestisci i dati mancanti in modo semplice con i fallback.
code language-handlebars {{#if fields.title}} <h1>{{{fields.title}}}</h1> {{snippet-not-found:else}} <h1>Untitled</h1> {{/if}} -
Utilizza sempre una struttura di documento HTML appropriata.
code language-handlebars <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{properties.title}}</title> </head> <body> <!-- your content here --> </body> </html> -
Esegui il test con diversi scenari di contenuto:
- Tutti i campi sono completamente compilati
- Campi opzionali mancanti
- Campi multivalore vuoti
- Nidificazione profonda (più livelli)
- Riferimenti non caricati
-
Utilizza elementi HTML semantici:
- Per una migliore accessibilità, utilizzare
<article>,<header>,<main>,<footer>,<time>,<address>o simili.
- Per una migliore accessibilità, utilizzare
-
Mantieni gli stili nel CSS.
- Utilizza
<style>tag o fogli di stile esterni. - Se possibile, evita gli stili in linea.
- Utilizza
-
Logica complessa documento:
- Usa commenti Handlebars
({{! }}). - Non utilizzare i commenti di HTML, visualizzati nell’output di rendering.
- Usa commenti Handlebars
Risoluzione di problemi troubleshooting
Alcuni suggerimenti per la risoluzione dei problemi includono:
<p>Hello World</p> visualizzato letteralmente{{{fields.description}}}{{{fields.author.name}}} è vuotomaxDepth sia sufficientemente profondo{{#each fields.tags}} per eseguire iterazioni di tutti gli elementi{{{fields.tags[0]}}} rendering vuoti{{{fields.tags.[0]}}}hasReferencedFragments è sempre falso?hydration=%7B%22enabled%22%3Atrue%7D; controllare anche {{#if referencesError}}{{#if}} o {{#each}} blocchi non chiusi. Aggiungere l’output di diagnostica: <pre>hasFields: {{hasFields}} | title: {{properties.title}}</pre>{{! comment }} invece di HTML <!-- comment -->{{#if fields.enabled}} è sempre truthy"false" è truthy in Handlebars. Solo i valori effettivi false, null, undefined, 0, "" e [] sono falsy.<, & visualizzato invece di <, &{{{fields.content}}}#each non è definita../ per l’ambito padre: {{{../name}}}; usa ../../ per l’ambito padre{{else}} in {{#each}}: {{#each fields.tags}}...{{else}}<p>No tags</p>{{/each}}Utilizzo delle risorse working-with-assets
Assets a cui si fa riferimento dai frammenti di contenuto viene sottoposto a pre-rendering come HTML da AEM. Pertanto, le parentesi graffe sono obbligatorie per tutti i riferimenti a risorse.
<img src="..." alt="..."><video> elemento<a href="...">Ricorda:
- Per i campi delle risorse, utilizza sempre le parentesi graffe.
Se si utilizzano parentesi graffe doppie, il tag HTML generato verrà eliminato e visualizzato come testo non elaborato anziché come immagine, video o collegamento.
Utilizzo campo risorsa asset-field-usage
Esempio di utilizzo del campo risorsa:
Helper per modelli personalizzati customer-template-helpers
Il sistema fornisce assistenti Handlebars personalizzati per la generazione di elementi HTML con attributi HTML personalizzati. Questi helper ti consentono di controllare il markup generato, gestendo al contempo la complessità dell’estrazione degli URL di origine dai contenuti pre-renderizzati.
Helper disponibili:
asset- Genera<img>tag con attributi personalizzatitext- Genera<span>tag per il wrapping del contenuto di testo con attributi personalizzati
Helper asset asset-helper
Sintassi:
Ricorda:
- Utilizzare le parentesi graffe triple
{{{ }}}con l’helper della risorsa, non le doppie.
Quattro esempi di base four-basic-examples
Quattro esempi di base sono:
Attributi supportati supported-attributes
Puoi aggiungere qualsiasi attributo HTML valido:
classclass="my-class another-class"idid="unique-id"altalt="Custom alt text" (overrides existing alt)data-*data-index="1" data-type="hero"aria-*aria-label="Description" aria-hidden="true"widthwidth="300"heightheight="200"loadingloading="lazy"stylestyle="border-radius: 8px;"Sostituisci testo alternativo override-alt-text
L’attributo alt dell’immagine originale può essere sovrascritto:
Esempio complesso complex-example
Un esempio complesso è:
Utilizzo con cicli using-with-loops
Helper risorse in loop:
Helper text text-helper
L’helper di testo genera un tag <span> che racchiude il contenuto di testo con classi CSS e attributi HTML personalizzati. Utile per formattare singoli campi di testo.
Sintassi:
Ricorda:
- Utilizzare le parentesi graffe triple
{{{ }}}con l’helper di testo, non le doppie.
Tre esempi di base three-basic-examples
Tre esempi di base sono:
Casi d’uso comuni common-use-cases
Alcuni casi d’uso comuni includono:
Con cicli with-loops
Un caso d’uso comune con i loop include:
Helper - Convalida degli attributi helpers-attribute-validation
Entrambi gli helper convalidano i nomi degli attributi prima di includerli nell’output.
Nomi di attributi validi:
-
Deve iniziare con una lettera (a-z, A-Z)
-
Può contenere solo lettere, cifre, trattini e trattini bassi; vedi le Convenzioni di denominazione
-
Senza distinzione tra maiuscole e minuscole
-
Ad esempio:
- Valido:
class,id,data-value,aria-label,my_attr,dataIndex1
- Non valido:
123-attr,-class,@special,$money
- Valido:
I nomi di attributo non validi vengono automaticamente ignorati con un avviso nei registri:
Ricorda:
- Verificare nei registri del server la presenza di avvisi relativi al formato di nome attributo “Bloccato non valido”.
Confronto tra output diretto e helper comparing-direct-output-to-helpers
Quando aumentare l’output diretto {{{fields.xxx}}}:
- Non è necessario utilizzare uno stile personalizzato
- Desideri l’output predefinito così com’è
- Il campo contiene HTML complessi che non desideri modificare
Quando utilizzare gli helper:
- È necessario aggiungere classi CSS per lo stile
- È necessario aggiungere attributi HTML personalizzati (
data-*,aria-*e altri) - Desideri una struttura HTML coerente e controllata
Confronto:
Riferimento rapido quick-reference
Vengono fornite alcune informazioni di riferimento rapido.
Variabili di contesto context-variables
Le variabili di contesto:
Accesso ai campi field-access
Come accedere ai campi:
Flusso di controllo control-flow
Flusso di controllo:
Variabili di loop loop-variables
Le variabili di loop:
Helper per modelli personalizzati custom-template-helpers
Il modello personalizzato aiuta a:
Risorse aggiuntive additional-resources
Sono disponibili risorse aggiuntive: