{"id":164053,"date":"2025-06-28T09:00:00","date_gmt":"2025-06-28T07:00:00","guid":{"rendered":"https:\/\/gtechgroup.it\/blog\/tag-template-html-componenti-riutilizzabili\/"},"modified":"2025-06-28T09:00:00","modified_gmt":"2025-06-28T07:00:00","slug":"tag-template-html-componenti-riutilizzabili","status":"publish","type":"post","link":"https:\/\/nuovosito.gtechgroup.it\/blog\/tag-template-html-componenti-riutilizzabili\/","title":{"rendered":"Il Tag Template in HTML: Creare Componenti Riutilizzabili"},"content":{"rendered":"<p style=\"text-align: justify;\">Il tag <code>&lt;template&gt;<\/code> \u00e8 uno degli elementi pi\u00f9 sottovalutati di HTML5, eppure rappresenta un meccanismo fondamentale per la creazione di contenuti riutilizzabili e dinamici. A differenza di tutti gli altri elementi HTML, il contenuto di un template non viene renderizzato dal browser, non viene eseguito e non \u00e8 visibile nella pagina fino a quando non viene esplicitamente attivato tramite JavaScript. Questa caratteristica unica lo rende uno strumento prezioso per lo sviluppo di interfacce web moderne e, in combinazione con i Web Components, per la creazione di componenti HTML personalizzati.<\/p>\n<h2>Come Funziona il Tag Template<\/h2>\n<p style=\"text-align: justify;\">L&#8217;elemento <code>&lt;template&gt;<\/code> definisce un frammento di markup HTML che il browser parsa ma non renderizza. Il contenuto all&#8217;interno del template \u00e8 quello che la specifica definisce <strong>&#8220;inerte&#8221;<\/strong> (inert): le immagini non vengono scaricate, gli script non vengono eseguiti, i fogli di stile non vengono applicati, gli elementi form non vengono inviati e i media non vengono riprodotti. Il browser prepara la struttura DOM del contenuto, rendendola pronta per essere clonata e utilizzata quando necessario.<\/p>\n<p style=\"text-align: justify;\">Questa inerzia \u00e8 la caratteristica chiave che distingue il template da approcci alternativi come nascondere elementi con display:none (che vengono comunque renderizzati e le cui risorse vengono scaricate) o inserire markup come stringa in un attributo data-* (che richiede il parsing ogni volta che viene utilizzata).<\/p>\n<p style=\"text-align: justify;\">Il contenuto del template \u00e8 accessibile tramite la propriet\u00e0 <strong>content<\/strong>, che restituisce un <strong>DocumentFragment<\/strong>. Il DocumentFragment \u00e8 un tipo speciale di nodo DOM che non ha un elemento genitore: quando viene inserito nel documento, vengono inseriti solo i suoi figli, non il fragment stesso. Questa caratteristica rende l&#8217;inserimento molto efficiente, poich\u00e9 avviene in un&#8217;unica operazione DOM.<\/p>\n<p style=\"text-align: justify;\">Il template pu\u00f2 essere posizionato ovunque nel documento HTML: nel <code>&lt;head&gt;<\/code>, nel <code>&lt;body&gt;<\/code>, all&#8217;interno di altri elementi. La posizione non influisce sul funzionamento, ma \u00e8 buona pratica posizionare i template alla fine del body o nell&#8217;head per mantenere il markup organizzato e separato dal contenuto visibile.<\/p>\n<h2>Clonare e Utilizzare i Template<\/h2>\n<p style=\"text-align: justify;\">Per utilizzare il contenuto di un template, il processo standard prevede tre passaggi: selezionare l&#8217;elemento template, clonare il suo contenuto e inserire il clone nel documento. La clonazione avviene tramite il metodo <strong>cloneNode(true)<\/strong> sulla propriet\u00e0 content, dove il parametro true indica una clonazione profonda (deep clone) che include tutti gli elementi figli.<\/p>\n<p style=\"text-align: justify;\">Dopo la clonazione, \u00e8 possibile <strong>modificare il contenuto<\/strong> del clone prima dell&#8217;inserimento. Si possono aggiornare testi, cambiare attributi, aggiungere event listener e personalizzare il markup in qualsiasi modo. Questa fase di personalizzazione \u00e8 ci\u00f2 che rende i template estremamente versatili: un singolo template pu\u00f2 generare molte istanze diverse.<\/p>\n<p style=\"text-align: justify;\">Un pattern frequente \u00e8 l&#8217;uso dei template per generare <strong>liste dinamiche<\/strong>. Si definisce un template con la struttura di un singolo elemento della lista, poi si itera su un array di dati, clonando il template per ogni elemento, personalizzandolo con i dati specifici e inserendolo nel contenitore della lista. Questo approccio \u00e8 pi\u00f9 performante della costruzione del markup tramite concatenazione di stringhe e innerHTML, poich\u00e9 il template viene parsato una sola volta.<\/p>\n<p style=\"text-align: justify;\">Per i progetti pi\u00f9 complessi, \u00e8 possibile annidare template all&#8217;interno di altri template e clonarli ricorsivamente. Tuttavia, per scenari con molti template e logica di rendering complessa, \u00e8 generalmente pi\u00f9 pratico utilizzare una libreria o un framework che offre un sistema di templating pi\u00f9 strutturato.<\/p>\n<h2>L&#8217;Elemento Slot: Proiezione dei Contenuti<\/h2>\n<p style=\"text-align: justify;\">L&#8217;elemento <code>&lt;slot&gt;<\/code> \u00e8 strettamente legato ai template nel contesto dei <strong>Web Components<\/strong>. Uno slot definisce un punto di inserzione nel Shadow DOM dove il contenuto fornito dall&#8217;utente del componente (il &#8220;light DOM&#8221;) viene proiettato. Questa proiezione non sposta fisicamente gli elementi nel Shadow DOM; li mostra nella posizione dello slot mantenendoli nel loro contesto originale.<\/p>\n<p style=\"text-align: justify;\">Lo <strong>slot predefinito<\/strong> (default slot) \u00e8 un elemento <code>&lt;slot&gt;<\/code> senza attributo name. Riceve tutto il contenuto del light DOM che non \u00e8 esplicitamente assegnato a uno slot con nome. Se il componente non riceve alcun contenuto, lo slot mostra il suo <strong>contenuto di fallback<\/strong>, ovvero qualsiasi markup inserito tra i tag di apertura e chiusura dello slot nel template.<\/p>\n<p style=\"text-align: justify;\">Questo meccanismo di fallback \u00e8 particolarmente utile per fornire valori predefiniti che vengono automaticamente sostituiti quando l&#8217;utente del componente fornisce il proprio contenuto. Ad esempio, un componente card potrebbe avere uno slot per il titolo con un fallback &#8220;Titolo predefinito&#8221; che viene mostrato solo se nessun titolo viene fornito.<\/p>\n<h2>Named Slot: Distribuire Contenuti in Pi\u00f9 Punti<\/h2>\n<p style=\"text-align: justify;\">I <strong>named slot<\/strong> (slot con nome) permettono di definire multiple zone di proiezione all&#8217;interno dello stesso componente. Nel template del componente, ogni slot con nome viene dichiarato con un attributo name univoco. Nel light DOM, gli elementi vengono assegnati a uno specifico slot tramite l&#8217;attributo <strong>slot<\/strong> il cui valore corrisponde al name dello slot di destinazione.<\/p>\n<p style=\"text-align: justify;\">Questa distribuzione multipla \u00e8 essenziale per componenti strutturati come card, dialog, layout e panel, dove diverse sezioni (header, body, footer, sidebar) devono poter essere personalizzate indipendentemente. Un componente dialog, ad esempio, potrebbe definire slot con nome &#8220;header&#8221;, &#8220;body&#8221; e &#8220;footer&#8221;, permettendo all&#8217;utente di personalizzare ciascuna sezione separatamente.<\/p>\n<p style=\"text-align: justify;\">L&#8217;evento <strong>slotchange<\/strong> viene generato quando il contenuto assegnato a uno slot cambia. Questo evento permette al componente di reagire dinamicamente quando il contenuto proiettato viene modificato, aggiunto o rimosso. Il metodo <strong>assignedNodes()<\/strong> sullo slot restituisce l&#8217;elenco dei nodi attualmente proiettati, mentre assignedNodes({ flatten: true }) include anche il contenuto di fallback se nessun nodo \u00e8 proiettato.<\/p>\n<p style=\"text-align: justify;\">\u00c8 possibile combinare slot con nome e slot predefinito nello stesso componente. Lo slot predefinito raccoglie tutto il contenuto &#8220;extra&#8221; che non \u00e8 esplicitamente assegnato a uno slot con nome, offrendo flessibilit\u00e0 sia al creatore del componente che al suo utilizzatore.<\/p>\n<h2>Pattern Pratici e Template Literals<\/h2>\n<p style=\"text-align: justify;\">Nel JavaScript moderno, i <strong>template literals<\/strong> (stringhe delimitate da backtick) offrono un&#8217;alternativa complementare al tag <code>&lt;template&gt;<\/code> per la generazione di markup dinamico. Mentre il tag HTML template \u00e8 ideale per strutture definite nel markup e riutilizzate pi\u00f9 volte, i template literals sono pi\u00f9 pratici per la generazione programmatica di HTML all&#8217;interno del codice JavaScript.<\/p>\n<p style=\"text-align: justify;\">Un pattern molto diffuso nei Web Components \u00e8 la definizione del template direttamente nel costruttore della classe, utilizzando template literals per generare la stringa HTML che viene poi assegnata alla propriet\u00e0 innerHTML del Shadow DOM. Questo approccio \u00e8 semplice e funzionale, ma meno performante del tag template per componenti istanziati molte volte, poich\u00e9 la stringa viene ri-parsata ad ogni istanza.<\/p>\n<p style=\"text-align: justify;\">Per il meglio dei due approcci, si pu\u00f2 creare un template programmaticamente: si genera un elemento template tramite document.createElement(&#8216;template&#8217;), si popola il suo innerHTML con un template literal, e lo si riutilizza clonandolo per ogni istanza del componente. Questa tecnica combina la praticit\u00e0 del template literal con la performance della clonazione.<\/p>\n<p style=\"text-align: justify;\">Librerie come <strong>Lit<\/strong> portano questo concetto ancora oltre con il tagged template literal html`&#8230;`, che offre rendering efficiente con diffing minimo, binding reattivo dei dati e una sintassi concisa. Per chi sviluppa Web Components professionalmente, Lit rappresenta un eccellente layer di produttivit\u00e0 sopra le API native. Per approfondire i Web Components nel loro insieme, consulta il nostro articolo su <a href=\"https:\/\/gtechgroup.it\/blog\/web-components-custom-elements-shadow-dom\/\">Custom Elements e Shadow DOM<\/a>.<\/p>\n<h2>Integrazione con i Web Components<\/h2>\n<p style=\"text-align: justify;\">Il tag template raggiunge la sua massima espressione quando viene utilizzato in combinazione con <strong>Custom Elements<\/strong> e <strong>Shadow DOM<\/strong>. In questo contesto, il template definisce la struttura interna del componente, il Shadow DOM la incapsula e protegge dagli stili esterni, e il Custom Element la rende disponibile come un nuovo tag HTML.<\/p>\n<p style=\"text-align: justify;\">Il flusso di creazione tipico prevede: definire un template con la struttura e gli stili del componente; nella classe del Custom Element, nel connectedCallback o nel costruttore, creare il Shadow DOM con attachShadow({mode: &#8216;open&#8217;}); clonare il contenuto del template e inserirlo nel shadow root; aggiungere la logica interattiva tramite event listener e metodi.<\/p>\n<p style=\"text-align: justify;\">Per i componenti che devono aggiornare il proprio contenuto in risposta a cambiamenti di propriet\u00e0 o attributi, il pattern pi\u00f9 semplice \u00e8 un metodo render() che rigenera il contenuto del Shadow DOM. Per performance ottimali con aggiornamenti frequenti, \u00e8 preferibile aggiornare solo le parti del DOM che sono effettivamente cambiate, anzich\u00e9 rigenerare l&#8217;intero contenuto.<\/p>\n<p style=\"text-align: justify;\">Il tag template in HTML \u00e8 uno strumento nativo potente che, combinato con le altre tecnologie dei Web Components, permette di creare componenti riutilizzabili, incapsulati e performanti senza dipendenze esterne. Padroneggiare questi strumenti nativi \u00e8 un investimento che ripaga in termini di longevit\u00e0, interoperabilit\u00e0 e comprensione profonda della piattaforma web.<\/p>\n<p style=\"text-align: justify;\">Hai bisogno di aiuto con la creazione di componenti web riutilizzabili? <strong>G Tech Group<\/strong> offre servizi di sviluppo web professionale e consulenza tecnica sulle architetture frontend. Contattaci a <strong>support@gtechgroup.it<\/strong> o via WhatsApp al <strong>0465 84 62 45<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Il tag &lt;template&gt; \u00e8 uno degli elementi pi\u00f9 sottovalutati di HTML5, eppure rappresenta un meccanismo fondamentale per la creazione di contenuti riutilizzabili e dinamici. A&hellip;<\/p>\n","protected":false},"author":2,"featured_media":164233,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1246],"tags":[787],"class_list":["post-164053","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html","tag-sviluppo-web"],"_links":{"self":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/164053","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/comments?post=164053"}],"version-history":[{"count":0,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/164053\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/media\/164233"}],"wp:attachment":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/media?parent=164053"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/categories?post=164053"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/tags?post=164053"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}