|
| 1 | +# Sistema di template |
| 2 | + |
| 3 | +Ogni elemento riutilizzabile di una pagina (header, footer, card, sezioni) è definito |
| 4 | +come un elemento [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template) |
| 5 | +in un file HTML separato nella cartella `src/templates/`. |
| 6 | + |
| 7 | +Non si usa nessuna libreria di templating esterna: è HTML e JavaScript standard, |
| 8 | +bundlato da Vite. |
| 9 | + |
| 10 | +## Struttura |
| 11 | + |
| 12 | +``` |
| 13 | +src/ |
| 14 | +├── templates/ |
| 15 | +│ ├── header.html # header del sito |
| 16 | +│ ├── footer.html # footer del sito |
| 17 | +│ ├── breadcrumb.html # navigazione breadcrumb |
| 18 | +│ ├── hero.html # sezione hero con titolo e descrizione |
| 19 | +│ ├── service-section.html # sezione con griglia di card |
| 20 | +│ └── service-card.html # singola card di servizio |
| 21 | +└── js/ |
| 22 | + └── templates.js # helper: fromHTML, render, renderList |
| 23 | +``` |
| 24 | + |
| 25 | +## Come funziona un template |
| 26 | + |
| 27 | +Ogni file in `src/templates/` contiene un unico elemento `<template>`. |
| 28 | +Vite lo importa come stringa (`?raw`) a build time — zero fetch a runtime. |
| 29 | + |
| 30 | +### Slot di testo — `data-tpl` |
| 31 | + |
| 32 | +```html |
| 33 | +<!-- src/templates/hero.html --> |
| 34 | +<template> |
| 35 | + <section class="hero"> |
| 36 | + <h1 data-tpl="titolo"></h1> |
| 37 | + <p data-tpl="descrizione"></p> |
| 38 | + </section> |
| 39 | +</template> |
| 40 | +``` |
| 41 | + |
| 42 | +```js |
| 43 | +render(tpl.hero, { |
| 44 | + titolo: 'Servizi', |
| 45 | + descrizione: 'I servizi della scuola.', |
| 46 | +}); |
| 47 | +``` |
| 48 | + |
| 49 | +### Slot attributi — `data-tpl-href` |
| 50 | + |
| 51 | +```html |
| 52 | +<!-- src/templates/service-card.html --> |
| 53 | +<template> |
| 54 | + <article class="service-card"> |
| 55 | + <a data-tpl-href="url"> |
| 56 | + <strong data-tpl="titolo"></strong> |
| 57 | + <p data-tpl="descrizione"></p> |
| 58 | + </a> |
| 59 | + </article> |
| 60 | +</template> |
| 61 | +``` |
| 62 | + |
| 63 | +### Liste — `renderList` |
| 64 | + |
| 65 | +```js |
| 66 | +const cards = [ |
| 67 | + { titolo: 'Iscrizioni', descrizione: '...', url: '#' }, |
| 68 | + { titolo: 'Pagamenti', descrizione: '...', url: '#' }, |
| 69 | +]; |
| 70 | + |
| 71 | +// riempie il container con una card per ogni elemento dell'array |
| 72 | +contenitore.append(renderList(tpl.serviceCard, cards)); |
| 73 | +``` |
| 74 | + |
| 75 | +### Template con container per lista — `data-cards` |
| 76 | + |
| 77 | +Il template `service-section.html` contiene un `<div data-cards>` che serve |
| 78 | +come punto di iniezione per le card. Il JS lo trova e ci inietta la lista: |
| 79 | + |
| 80 | +```js |
| 81 | +const sectionFrag = render(tpl.serviceSection, { titolo: sezione.titolo }); |
| 82 | +sectionFrag.querySelector('[data-cards]').append(renderList(tpl.serviceCard, sezione.cards)); |
| 83 | +rootSections.append(sectionFrag); |
| 84 | +``` |
| 85 | + |
| 86 | +## Aggiungere una nuova pagina con template |
| 87 | + |
| 88 | +1. Crea `src/pages/mia-pagina.html` (shell minimale — solo `<div id="root-*">`). |
| 89 | +2. Crea `src/js/pages/mia-pagina.js`. |
| 90 | +3. Importa i template che ti servono: |
| 91 | + ```js |
| 92 | + import { render, renderList, fromHTML } from '../templates.js'; |
| 93 | + import heroHTML from '../../templates/hero.html?raw'; |
| 94 | + const tpl = { hero: fromHTML(heroHTML) }; |
| 95 | + ``` |
| 96 | +4. Definisci i dati e chiama `render()` / `renderList()`. |
| 97 | +5. Aggiungi il link in `src/index.html`. |
| 98 | + |
| 99 | +## Aggiungere un nuovo template |
| 100 | + |
| 101 | +1. Crea `src/templates/mio-template.html`: |
| 102 | + ```html |
| 103 | + <template> |
| 104 | + <div class="mio-componente"> |
| 105 | + <h3 data-tpl="titolo"></h3> |
| 106 | + <a data-tpl-href="url" data-tpl="etichetta"></a> |
| 107 | + </div> |
| 108 | + </template> |
| 109 | + ``` |
| 110 | +2. Importalo nel JS della pagina: |
| 111 | + ```js |
| 112 | + import mioHTML from '../../templates/mio-template.html?raw'; |
| 113 | + const tpl = { mio: fromHTML(mioHTML) }; |
| 114 | + ``` |
| 115 | +3. Usalo con `render(tpl.mio, { titolo: '...', url: '#', etichetta: '...' })`. |
| 116 | + |
| 117 | +## API dell'helper (`src/js/templates.js`) |
| 118 | + |
| 119 | +| Funzione | Parametri | Restituisce | Descrizione | |
| 120 | +|---|---|---|---| |
| 121 | +| `fromHTML(html)` | `string` | `HTMLTemplateElement` | Parsa una stringa `?raw` e restituisce il `<template>` | |
| 122 | +| `render(tpl, data)` | `HTMLTemplateElement`, `object` | `DocumentFragment` | Clona il template e riempie gli slot | |
| 123 | +| `renderList(tpl, items)` | `HTMLTemplateElement`, `object[]` | `DocumentFragment` | Chiama `render` per ogni elemento dell'array | |
| 124 | + |
| 125 | +## Riferimento — pagina esempio |
| 126 | + |
| 127 | +Vedi `src/pages/servizio.html` + `src/js/pages/servizio.js` per un esempio |
| 128 | +completo con header, footer, breadcrumb, hero e tre sezioni di card. |
0 commit comments