TemplatePro - Documentazione Ufficiale
Aggiornato il 25-11-2025 alla versione 0.8.0 del linguaggio TemplatePro.
Ecco un esempio di applicazione web dinamica realizzata con DMVCFramework, TemplatePro e HTMX.

TemplatePro è un motore di templating moderno e versatile progettato per semplificare la generazione dinamica di HTML, contenuti email e file di testo. Con una sintassi ispirata a sistemi di templating popolari come Jinja e Smarty, TemplatePro offre funzionalità potenti tra cui blocchi condizionali, cicli, ereditarietà dei template, macro riutilizzabili e supporto per dati JSON.
La documentazione per le versioni precedenti alla 0.8.0 è disponibile qui.
Questo articolo è disponibile anche in inglese.
Dalla versione 0.7.0 TemplatePro è case insensitive sia nei nomi delle variabili che nelle direttive.
Quick Start
Il modo più semplice per usare TemplatePro: compila una stringa template, imposta le variabili e genera l’output.
var
lCompiler: TTProCompiler;
lCompiledTemplate: ITProCompiledTemplate;
begin
lCompiler := TTProCompiler.Create();
try
lCompiledTemplate := lCompiler.Compile('Ciao {{:name}}! Hai {{:age}} anni.');
finally
lCompiler.Free;
end;
lCompiledTemplate.SetData('name', 'Daniele');
lCompiledTemplate.SetData('age', 50);
WriteLn(lCompiledTemplate.Render);
end;
Output:
Ciao Daniele! Hai 50 anni.
Tutto qui! Compila un template, imposta alcune variabili e genera l’output. Ora esploriamo tutte le funzionalità che TemplatePro offre.
Esempio Completo
Per scenari reali, spesso avrai bisogno di filtri per trasformare i dati e funzioni personalizzate per esigenze di formattazione specifiche.
program tproconsole;
{$APPTYPE CONSOLE}
uses
TemplatePro,
System.Rtti,
System.SysUtils;
// Filtro personalizzato che racchiude il testo tra parentesi quadre
function AddSquareBrackets(
const aValue: TValue;
const aParameters: TArray<TFilterParameter>): TValue;
begin
Result := '[' + aValue.AsString + ']';
end;
var
lCompiler: TTProCompiler;
lCompiledTemplate: ITProCompiledTemplate;
begin
lCompiler := TTProCompiler.Create();
try
lCompiledTemplate := lCompiler.Compile(
'Ciao {{:name|brackets}}! Oggi è {{:today|datetostr}}.');
finally
lCompiler.Free;
end;
lCompiledTemplate.SetData('name', 'Daniele Teti');
lCompiledTemplate.SetData('today', Date);
lCompiledTemplate.AddFilter('brackets', AddSquareBrackets);
WriteLn(lCompiledTemplate.Render);
// Output: Ciao [Daniele Teti]! Oggi è 2025-11-25.
end.
Per migliori prestazioni di avvio in produzione, salva e ricarica i template compilati da disco:
// Salva il template compilato su file
lCompiledTemplate.SaveToFile('template.tpc');
// Carica un template pre-compilato (deve essere la stessa versione di TemplatePro)
lCompiledTemplate := TTProCompiledTemplate.CreateFromFile('template.tpc');
1. Interpolazione delle Variabili
Usa la sintassi {{:variable}} per iniettare contenuto dinamico nei template.
Variabili Semplici
Visualizza valori base come stringhe, numeri o date direttamente nell’output:
Ciao, {{:name}}!
Hai {{:age}} anni.
Accesso alle Proprietà degli Oggetti
Quando lavori con oggetti Delphi, accedi alle proprietà annidate usando la notazione con punto:
{{:user.profile.first_name}} {{:user.profile.last_name}}
Email: {{:user.contact.email}}
Accesso agli Elementi di un Array
Per dati di tipo array o lista, usa la notazione con parentesi quadre con indici a base zero:
Primo elemento: {{:items[0]}}
Secondo elemento: {{:items[1]}}
Variabili Null o Non Definite
Le variabili mancanti o null vengono renderizzate come stringhe vuote, evitando errori a runtime:
Questo sarà vuoto se non definito: {{:undefined_var}}
2. Logica Condizionale con if/else
Controlla quale contenuto appare in base alle condizioni sui dati.
Blocchi Condizionali Base
Mostra contenuto diverso agli utenti loggati rispetto agli anonimi:
{{if user_logged_in}}
Bentornato, {{:username}}!
{{else}}
Effettua il login per continuare.
{{endif}}
Valutazione della Veridicità
TemplatePro valuta i diversi tipi di dato per la loro veridicità:
- Stringhe: le stringhe vuote sono false, le stringhe non vuote sono vere
- Numeri: lo zero è falso, i numeri diversi da zero sono veri
- Oggetti: gli oggetti null sono falsi, gli oggetti non null sono veri
- Collezioni: le collezioni/dataset vuoti sono falsi, quelli non vuoti sono veri
- Booleani: i valori true/false funzionano come previsto
Espressioni Condizionali con Filtri
Usa filtri di confronto per implementare logica di business come verifica dell’età o validazione input:
{{if age|ge,18}}
Sei maggiorenne.
{{else}}
Sei minorenne.
{{endif}}
{{if username|contains,"admin"}}
Utente amministratore rilevato.
{{endif}}
{{if password|eq,confirm_password}}
Le password corrispondono.
{{else}}
Conferma password fallita.
{{endif}}
Filtri Logici and e or
Combina più condizioni per scenari di validazione complessi:
{{if value1|and,value2}}
Entrambi sono veri
{{else}}
Almeno uno è falso
{{endif}}
{{if value1|or,value2}}
Almeno uno è vero
{{else}}
Entrambi sono falsi
{{endif}}
Questi filtri sono utili per verificare più requisiti contemporaneamente:
{{if user.active|and,user.verified}}
Account completamente attivo
{{endif}}
{{if email_error|or,password_error}}
Ci sono errori nel form
{{endif}}
3. Cicli con for .. in
Itera sulle collezioni per generare contenuto ripetuto come liste, tabelle o card.
Struttura Base
Renderizza una semplice lista di persone da una collezione:
{{for person in people}}
- {{:person.first_name}} {{:person.last_name}}
{{endfor}}
Controllo del Ciclo con continue
Salta certi elementi in base a condizioni, come filtrare prodotti fuori produzione:
{{for product in products}}
{{if product.discontinued|eq,true}}
{{continue}}
{{endif}}
Prodotto: {{:product.name}} - Prezzo: {{:product.price}}
{{endfor}}
Cicli Annidati
Visualizza dati gerarchici come contatti con più numeri di telefono:
{{for person in people}}
{{:person.first_name}} {{:person.last_name}}
{{for phone in person.phones}}
- {{:phone.type}}: {{:phone.number}}
{{endfor}}
{{endfor}}
Pseudo-Variabili nei Cicli
Usa le variabili di ciclo incorporate per numerazione, striping zebrato o stili alternati:
@@index: indice dell’iterazione corrente (a base 1)@@odd: vero per gli elementi con indice dispari@@even: vero per gli elementi con indice pari
{{for customer in customers}}
{{:customer.@@index}}. {{:customer.Name}}
{{if customer.@@odd}}
(Posizione dispari)
{{endif}}
{{if customer.@@even}}
(Posizione pari)
{{endif}}
{{endfor}}
4. Dataset
Renderizza record TDataSet di Delphi direttamente nei template per applicazioni database-driven:
{{if customers}}
<table>
<tr><th>Codice</th><th>Nome</th><th>Città</th></tr>
{{for customer in customers}}
<tr>
<td>{{:customer.Code}}</td>
<td>{{:customer.Name}}</td>
<td>{{:customer.City}}</td>
</tr>
{{endfor}}
</table>
{{else}}
<p>Nessun cliente nel database.</p>
{{endif}}
5. Filtri Built-in
Trasforma i valori in output usando la sintassi pipe {{:value|filter}}.
Filtri di Trasformazione Testo
Cambia il case del testo per requisiti di visualizzazione o formattazione consistente:
Originale: {{:name}}
Maiuscolo: {{:name|uppercase}}
Minuscolo: {{:name|lowercase}}
Capitalizzato: {{:name|capitalize}}
Filtri di Padding
Allinea il testo in output a larghezza fissa come report o applicazioni console:
Padding a destra: "{{:code|rpad,10}}"
Padding a destra con trattini: "{{:code|rpad,10,"-"}}"
Padding a sinistra: "{{:code|lpad,8}}"
Padding a sinistra con zeri: "{{:id|lpad,6,"0"}}"
Filtri Data e Ora
Formatta le date per diverse localizzazioni o requisiti di visualizzazione:
Formato sistema: {{:birth_date|datetostr}}
Formato personalizzato: {{:birth_date|datetostr,"dd/mm/yyyy"}}
DateTime: {{:created_at|datetimetostr,"yyyy-mm-dd hh:nn:ss"}}
Formato ISO: {{:timestamp|datetoiso8601}}
Filtri Numerici
Visualizza numeri con simboli di valuta, decimali o formati percentuale:
Formattato: {{:price|formatfloat,"$#,##0.00"}}
Percentuale: {{:rate|formatfloat,"0.00%"}}
Filtri di Elaborazione Testo
Tronca testo lungo o escapa caratteri HTML per sicurezza:
Troncato: {{:description|trunc,50}}
HTML encoded: {{:user_input|htmlencode}}
Versione: {{:""|version}}
Il Filtro default
Fornisce valori di fallback per dati vuoti, null o zero per evitare output vuoti:
Valore con contenuto: {{:value|default,"fallback"}}
Valore vuoto/zero: {{:zero_value|default,"N/A"}}
Default numerico: {{:quantity|default,1}}
Concatena default per fallback multi-livello:
Benvenuto, {{:nickname|default,name|default,"Ospite"}}!
Quantità: {{:qty|default,1}}
Riferimento Completo Filtri Built-in
| Filtro | Descrizione | Esempio |
|---|---|---|
uppercase |
Converte in maiuscolo | {{:name|uppercase}} |
lowercase |
Converte in minuscolo | {{:name|lowercase}} |
capitalize |
Capitalizza ogni parola | {{:title|capitalize}} |
rpad,length[,char] |
Padding a destra fino alla lunghezza | {{:code|rpad,10,"-"}} |
lpad,length[,char] |
Padding a sinistra fino alla lunghezza | {{:id|lpad,6,"0"}} |
datetostr[,format] |
Formatta data | {{:date|datetostr,"dd/mm/yyyy"}} |
datetimetostr[,format] |
Formatta datetime | {{:datetime|datetimetostr}} |
datetoiso8601 |
Formato ISO 8601 | {{:date|datetoiso8601}} |
formatfloat,format |
Formatta numeri | {{:price|formatfloat,"$0.00"}} |
trunc,length |
Tronca testo | {{:text|trunc,50}} |
htmlencode |
Codifica HTML | {{:input|htmlencode}} |
default,value |
Valore di fallback | {{:var|default,"N/A"}} |
version |
Versione TemplatePro | {{:|version}} |
totrue |
Sempre vero | {{:var|totrue}} |
tofalse |
Sempre falso | {{:var|tofalse}} |
| Filtri di Confronto | ||
eq,value |
Uguale a | {{if age|eq,25}} |
ne,value |
Diverso da | {{if status|ne,"inactive"}} |
gt,value |
Maggiore di | {{if score|gt,80}} |
ge,value |
Maggiore o uguale | {{if age|ge,18}} |
lt,value |
Minore di | {{if price|lt,100}} |
le,value |
Minore o uguale | {{if items|le,10}} |
contains,text |
Contiene testo | {{if name|contains,"John"}} |
icontains,text |
Contiene (case-insensitive) | {{if email|icontains,"gmail"}} |
| Filtri Logici | ||
and,variable |
AND logico | {{if a|and,b}} |
or,variable |
OR logico | {{if a|or,b}} |
6. Filtri Concatenati
Applica trasformazioni multiple in sequenza - l’output di ogni filtro alimenta il successivo.
Sintassi
{{:variable|filter1|filter2|filter3}}
Esempi Pratici
Normalizza testo, combina operazioni di padding o proteggi input utente con trasformazioni multiple:
{{:name|lowercase|capitalize}}
{{:code|lpad,5|rpad,10}}
{{:description|trunc,50|htmlencode}}
Nel primo esempio, il valore viene prima convertito in minuscolo, poi capitalizzato. Nel secondo, viene applicato prima il padding a sinistra fino a 5 caratteri, poi il padding a destra fino a 10 caratteri totali.
Casi d’Uso Comuni
Costruisci pipeline di formattazione complesse per codici prodotto, contenuti generati dagli utenti o normalizzazione dati:
Formattazione complessa: {{:product_code|uppercase|lpad,10,"0"}}
Sicurezza output: {{:user_input|trunc,100|htmlencode}}
Normalizzazione: {{:email|lowercase|default,"noemail@example.com"}}
I filtri concatenati sono particolarmente utili per:
- Applicare trasformazioni multiple in modo leggibile
- Creare pipeline di elaborazione dati
- Combinare formattazione e sicurezza
7. Filtri Personalizzati
Estendi TemplatePro con le tue funzioni di trasformazione.
Signature delle Funzioni Filtro
Definisci filtri come funzioni regolari o metodi anonimi:
// Funzione regolare
TTProTemplateFunction =
function(const aValue: TValue; const aParameters: TArray<TFilterParameter>): TValue;
// Metodo anonimo
TTProTemplateAnonFunction =
reference to function(const aValue: TValue; const aParameters: TArray<TFilterParameter>): TValue;
Esempio di Filtro Personalizzato Semplice
Crea un filtro che racchiude il testo tra parentesi quadre per evidenziarlo:
function AddSquareBrackets(const aValue: TValue;
const aParameters: TArray<TFilterParameter>): TValue;
begin
Result := '[' + aValue.AsString + ']';
end;
// Registra il filtro
lCompiledTemplate.AddFilter('brackets', AddSquareBrackets);
Utilizzo:
Originale: {{:username}}
Con parentesi: {{:username|brackets}}
Filtro con Parametri
Crea un filtro configurabile che ripete il testo un numero specificato di volte:
function RepeatText(const aValue: TValue;
const aParameters: TArray<TFilterParameter>): TValue;
var
lText: string;
lCount, i: Integer;
begin
lText := aValue.AsString;
lCount := aParameters[0].ParIntValue;
Result := '';
for i := 1 to lCount do
Result := Result + lText;
end;
lCompiledTemplate.AddFilter('repeat', RepeatText);
Utilizzo:
Ripetuto: {{:char|repeat,5}}
Variabili come Parametri dei Filtri
Passa valori dinamici ai filtri per formattazione flessibile guidata dai dati:
{{:message|truncate,max_length}}
{{:price|formatfloat,number_format}}
{{if score|gt,passing_grade}}
Congratulazioni!
{{endif}}
8. Macro
Definisci blocchi di template riutilizzabili per evitare ripetizioni e mantenere consistenza.
Definizione Base e Chiamata
Crea una macro di saluto semplice che può essere chiamata con nomi diversi:
{{macro greeting(name)}}
Hello, {{:name}}!
{{endmacro}}
{{call greeting("World")}}
{{call greeting("TemplatePro")}}
Output:
Hello, World!
Hello, TemplatePro!
Macro con Parametri Multipli
Costruisci componenti UI riutilizzabili come card che accettano valori multipli:
{{macro card(title, content)}}
<div class="card">
<h3>{{:title}}</h3>
<p>{{:content}}</p>
</div>
{{endmacro}}
{{call card("Benvenuto", "Questo è il contenuto")}}
{{call card("Seconda Card", "Altro contenuto qui")}}
Macro senza Parametri
Crea separatori visivi semplici o elementi decorativi:
{{macro separator()}}
---
{{endmacro}}
Inizio
{{call separator()}}
Centro
{{call separator()}}
Fine
Macro con Filtri
Applica trasformazioni all’interno delle macro per output formattato:
{{macro format(text)}}
[{{:text|uppercase}}]
{{endmacro}}
{{call format("hello")}}
{{call format(user_name)}}
Macro con Logica Condizionale
Crea componenti adattivi che cambiano comportamento in base ai parametri:
{{macro greeting(name, formal)}}
{{if formal}}
Buongiorno, Sig. {{:name}}.
{{else}}
Ciao {{:name}}!
{{endif}}
{{endmacro}}
{{call greeting("Rossi", true)}}
{{call greeting("Marco", false)}}
Macro Annidate
Componi componenti complessi facendo chiamare altre macro alle macro:
{{macro inner(text)}}
*{{:text}}*
{{endmacro}}
{{macro outer(text)}}
[{{call inner(text)}}]
{{endmacro}}
{{call outer("nested")}}
Output:
[*nested*]
Macro nei Cicli
Combina macro con cicli per renderizzazione consistente degli elementi:
{{macro item(name, value)}}
- {{:name}}: {{:value}}
{{endmacro}}
{{for obj in objects}}
{{call item(obj.Name, obj.Value)}}
{{endfor}}
Passare Variabili alle Macro
Mescola valori letterali e variabili dinamiche nelle chiamate alle macro:
{{macro showValue(label, value)}}
{{:label}}: {{:value}}
{{endmacro}}
{{call showValue("Nome", "Mario")}}
{{call showValue("Titolo", page_title)}}
9. Funzioni Template
Le funzioni sono filtri applicati a valori vuoti - utili per generare contenuto dinamico senza input.
Ottieni la versione corrente di TemplatePro:
Versione corrente: {{:|version}}
Esempio di Funzione Personalizzata
Crea una funzione generatore di UUID per identificatori univoci:
function GenerateUUID(const aValue: TValue;
const aParameters: TArray<TFilterParameter>): TValue;
begin
if not aValue.IsEmpty then
raise ETProRenderException.Create('"GenerateUUID" è una funzione, non un filtro');
Result := TGuid.NewGuid.ToString;
end;
lCompiledTemplate.AddFilter('uuid', GenerateUUID);
Utilizzo:
Nuovo ID: {{:|uuid}}
10. Dati JSON
Renderizza strutture JSON annidate complesse con cicli e condizionali:
{{for person in people}}
{{:person.@@index}}) {{:person.first_name|uppercase}} {{:person.last_name|uppercase}}
Età: {{:person.age}}
{{if person.devices}}
Dispositivi:
{{for device in person.devices}}
{{:device.@@index}}. {{:device.name}} ({{:device.type}})
{{endfor}}
{{endif}}
{{endfor}}
11. Ereditarietà dei Template
Costruisci layout di pagina consistenti estendendo un template base con blocchi personalizzati.
Template Base (base.tpro)
Definisci la struttura comune con blocchi sostituibili:
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>{{block "title"}}Titolo Default{{endblock}}</title>
{{block "extra_css"}}{{endblock}}
</head>
<body>
<header>
{{block "navigation"}}
<nav>Menu default</nav>
{{endblock}}
</header>
<main>
{{block "content"}}
<p>Contenuto default.</p>
{{endblock}}
</main>
<footer>
{{block "footer"}}
<p>Footer default</p>
{{endblock}}
</footer>
{{block "extra_js"}}{{endblock}}
</body>
</html>
Template Figlio
Sovrascrivi blocchi specifici ereditando il resto:
{{extends "base.tpro"}}
{{block "title"}}{{:page_title}} - Il Mio Sito{{endblock}}
{{block "content"}}
<h1>{{:page_title}}</h1>
<p>{{:content}}</p>
{{endblock}}
{{block "extra_js"}}
<script src="/js/page.js"></script>
{{endblock}}
Regole di Ereditarietà
- Ereditarietà a singolo livello: i template figli possono estendere solo un template padre
- Override dei blocchi: se un figlio definisce un blocco esistente, sovrascrive quello del padre
- Blocchi default: se un figlio non definisce un blocco, viene usato il contenuto default del padre
- Contenuto ignorato: qualsiasi contenuto fuori dai blocchi nei template figli viene ignorato
12. Inclusione di Template
Dividi i template in file riutilizzabili per header, footer e componenti condivisi:
{{include "header.tpro"}}
<main>
<h1>{{:page_title}}</h1>
<p>{{:content}}</p>
</main>
{{include "footer.tpro"}}
Inclusione con Sottodirectory
Organizza i template in cartelle per una migliore manutenibilità:
{{include "partials/navigation.tpro"}}
{{include "components/product-card.tpro"}}
13. Tipi Nullable
Gestisci valori opzionali con controlli condizionali:
{{if user.middle_name}}
Nome completo: {{:user.first_name}} {{:user.middle_name}} {{:user.last_name}}
{{else}}
Nome: {{:user.first_name}} {{:user.last_name}}
{{endif}}
{{if order.shipped_date}}
Spedito: {{:order.shipped_date|datetostr}}
{{else}}
Stato: In elaborazione
{{endif}}
14. Best Practice e Performance
Compilazione dei Template
- Compila i template una volta e riutilizza la versione compilata
- Salva i template compilati su file per migliori prestazioni di avvio
- Usa strategie di caching appropriate per ambienti di produzione
Uso dei Filtri
- Usa i filtri built-in quando possibile (sono ottimizzati)
- Minimizza filtri personalizzati complessi nei cicli
- Considera di pre-elaborare i dati invece di logica template complessa
Organizzazione dei Template
- Usa l’ereditarietà per layout consistenti
- Dividi template grandi in componenti più piccoli e riutilizzabili
- Organizza i template in strutture di directory logiche
- Usa le macro per componenti ripetuti
Gestione degli Errori
Racchiudi le operazioni sui template in blocchi try-except per gestire errori di compilazione e rendering:
try
lCompiledTemplate := lCompiler.Compile(lTemplate);
lResult := lCompiledTemplate.Render;
except
on E: ETProCompilerException do
// Gestisci errori di compilazione
ShowMessage('Errore di compilazione template: ' + E.Message);
on E: ETProRenderException do
// Gestisci errori di rendering
ShowMessage('Errore di rendering template: ' + E.Message);
on E: Exception do
// Gestisci altri errori
ShowMessage('Errore inaspettato: ' + E.Message);
end;
Conclusione
TemplatePro è un motore di templating completo e potente che fornisce agli sviluppatori la flessibilità e il controllo necessari per lo sviluppo di applicazioni moderne. Le sue caratteristiche principali includono:
- Sintassi Intuitiva: sintassi pulita e leggibile ispirata a motori popolari
- Logica Potente: istruzioni condizionali e costrutti di ciclo completi
- Ereditarietà dei Template: layout riutilizzabili e gerarchie di componenti
- Macro: blocchi di codice riutilizzabili con parametri
- Filtri Concatenati: pipeline flessibili di trasformazione dati
- Filtri Estesi: ricco set di filtri built-in più supporto per filtri personalizzati
- Eccellenza JSON: supporto di prima classe per strutture dati JSON complesse
- Type Safety: eccellente gestione del sistema di tipi Delphi inclusi i nullable
- Design Modulare: inclusione template e sviluppo basato su componenti
Che tu stia costruendo semplici email HTML, applicazioni web complesse o sistemi di generazione report dinamici, TemplatePro fornisce gli strumenti necessari per creare template manutenibili, efficienti e potenti.
Link e Risorse
- Repository GitHub TemplatePro
- Unit test per esempi completi e casi limite
- Gruppo di Supporto DelphiMVCFramework su Facebook (include supporto TemplatePro)
- Supporta il Progetto su Patreon
- Documentazione precedente
Versione Corrente: 0.8.0 - Aggiornato Novembre 2025
Comments
comments powered by Disqus