koa-classic-server 2.0.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +553 -127
  2. package/__tests__/directory-sorting-links.test.js +135 -0
  3. package/__tests__/ejs.test.js +299 -0
  4. package/__tests__/performance.test.js +75 -6
  5. package/__tests__/publicWwwTest/ejs-templates/complex.ejs +56 -0
  6. package/__tests__/publicWwwTest/ejs-templates/index.ejs +30 -0
  7. package/__tests__/publicWwwTest/ejs-templates/simple.ejs +13 -0
  8. package/__tests__/publicWwwTest/ejs-templates/with-conditional.ejs +28 -0
  9. package/__tests__/publicWwwTest/ejs-templates/with-escaping.ejs +26 -0
  10. package/__tests__/publicWwwTest/ejs-templates/with-loop.ejs +16 -0
  11. package/{scripts → __tests__}/setup-benchmark.js +1 -1
  12. package/docs/CODE_REVIEW.md +298 -0
  13. package/docs/FLOW_DIAGRAM.md +952 -0
  14. package/docs/template-engine/TEMPLATE_ENGINE_GUIDE.md +1734 -0
  15. package/docs/template-engine/esempi-incrementali.js +192 -0
  16. package/docs/template-engine/examples/esempio1-nessun-dato.ejs +12 -0
  17. package/docs/template-engine/examples/esempio2-una-variabile.ejs +11 -0
  18. package/docs/template-engine/examples/esempio3-piu-variabili.ejs +15 -0
  19. package/docs/template-engine/examples/esempio4-condizionale.ejs +18 -0
  20. package/docs/template-engine/examples/esempio5-loop.ejs +18 -0
  21. package/docs/template-engine/examples/index-esempi.html +181 -0
  22. package/docs/template-engine/examples/index.html +40 -0
  23. package/docs/template-engine/examples/test.ejs +64 -0
  24. package/index.cjs +186 -35
  25. package/package.json +9 -6
  26. package/CREATE_RELEASE.sh +0 -53
  27. package/publish-to-npm.sh +0 -65
  28. /package/{benchmark-results-baseline-v1.2.0.txt → __tests__/benchmark-results-baseline-v1.2.0.txt} +0 -0
  29. /package/{benchmark-results-optimized-v2.0.0.txt → __tests__/benchmark-results-optimized-v2.0.0.txt} +0 -0
  30. /package/{benchmark.js → __tests__/benchmark.js} +0 -0
  31. /package/{customTest → __tests__/customTest}/README.md +0 -0
  32. /package/{customTest → __tests__/customTest}/loadConfig.util.js +0 -0
  33. /package/{customTest → __tests__/customTest}/serversToLoad.util.js +0 -0
  34. /package/{demo-regex-index.js → __tests__/demo-regex-index.js} +0 -0
  35. /package/{test-regex-quick.js → __tests__/test-regex-quick.js} +0 -0
  36. /package/{BENCHMARKS.md → docs/BENCHMARKS.md} +0 -0
  37. /package/{CHANGELOG.md → docs/CHANGELOG.md} +0 -0
  38. /package/{DEBUG_REPORT.md → docs/DEBUG_REPORT.md} +0 -0
  39. /package/{DOCUMENTATION.md → docs/DOCUMENTATION.md} +0 -0
  40. /package/{EXAMPLES_INDEX_OPTION.md → docs/EXAMPLES_INDEX_OPTION.md} +0 -0
  41. /package/{INDEX_OPTION_PRIORITY.md → docs/INDEX_OPTION_PRIORITY.md} +0 -0
  42. /package/{OPTIMIZATION_HTTP_CACHING.md → docs/OPTIMIZATION_HTTP_CACHING.md} +0 -0
  43. /package/{PERFORMANCE_ANALYSIS.md → docs/PERFORMANCE_ANALYSIS.md} +0 -0
  44. /package/{PERFORMANCE_COMPARISON.md → docs/PERFORMANCE_COMPARISON.md} +0 -0
  45. /package/{noteExports.md → docs/noteExports.md} +0 -0
@@ -0,0 +1,192 @@
1
+ const koa = require("koa");
2
+ const app = new koa();
3
+ const port = 3000;
4
+ const classicServer = require("../../index.cjs");
5
+ const ejs = require("ejs");
6
+ const path = require("path");
7
+
8
+ // ============================================================
9
+ // ESEMPIO 1: Nessun dato passato
10
+ // ============================================================
11
+ // Template: esempio1-nessun-dato.ejs
12
+ // Uso: Non serve passare nessun dato
13
+ // URL: http://localhost:3000/esempio1-nessun-dato.ejs
14
+
15
+ const esempio1 = async (ctx, next, filePath) => {
16
+ try {
17
+ // Nessun dato passato - il template non usa variabili
18
+ ctx.body = await ejs.renderFile(filePath, {});
19
+ ctx.type = 'text/html';
20
+ } catch (error) {
21
+ console.error('Errore:', error.message);
22
+ ctx.status = 500;
23
+ ctx.body = `<h1>Errore</h1><pre>${error.message}</pre>`;
24
+ }
25
+ };
26
+
27
+ // ============================================================
28
+ // ESEMPIO 2: Una sola variabile
29
+ // ============================================================
30
+ // Template: esempio2-una-variabile.ejs
31
+ // Uso: Passa solo "nome"
32
+ // URL: http://localhost:3000/esempio2-una-variabile.ejs
33
+
34
+ const esempio2 = async (ctx, next, filePath) => {
35
+ try {
36
+ // Passa UNA variabile
37
+ ctx.body = await ejs.renderFile(filePath, {
38
+ nome: 'Mario'
39
+ });
40
+ ctx.type = 'text/html';
41
+ } catch (error) {
42
+ console.error('Errore:', error.message);
43
+ ctx.status = 500;
44
+ ctx.body = `<h1>Errore</h1><pre>${error.message}</pre>`;
45
+ }
46
+ };
47
+
48
+ // ============================================================
49
+ // ESEMPIO 3: Più variabili
50
+ // ============================================================
51
+ // Template: esempio3-piu-variabili.ejs
52
+ // Uso: Passa "nome", "eta", "citta"
53
+ // URL: http://localhost:3000/esempio3-piu-variabili.ejs
54
+
55
+ const esempio3 = async (ctx, next, filePath) => {
56
+ try {
57
+ // Passa PIÙ variabili
58
+ ctx.body = await ejs.renderFile(filePath, {
59
+ nome: 'Mario',
60
+ eta: 30,
61
+ citta: 'Roma'
62
+ });
63
+ ctx.type = 'text/html';
64
+ } catch (error) {
65
+ console.error('Errore:', error.message);
66
+ ctx.status = 500;
67
+ ctx.body = `<h1>Errore</h1><pre>${error.message}</pre>`;
68
+ }
69
+ };
70
+
71
+ // ============================================================
72
+ // ESEMPIO 4: Condizionale (if/else)
73
+ // ============================================================
74
+ // Template: esempio4-condizionale.ejs
75
+ // Uso: Passa "autenticato" e "nome"
76
+ // URL: http://localhost:3000/esempio4-condizionale.ejs
77
+
78
+ const esempio4 = async (ctx, next, filePath) => {
79
+ try {
80
+ // Passa variabili per logica condizionale
81
+ ctx.body = await ejs.renderFile(filePath, {
82
+ autenticato: true, // Cambia in false per vedere il messaggio diverso
83
+ nome: 'Mario'
84
+ });
85
+ ctx.type = 'text/html';
86
+ } catch (error) {
87
+ console.error('Errore:', error.message);
88
+ ctx.status = 500;
89
+ ctx.body = `<h1>Errore</h1><pre>${error.message}</pre>`;
90
+ }
91
+ };
92
+
93
+ // ============================================================
94
+ // ESEMPIO 5: Loop (forEach)
95
+ // ============================================================
96
+ // Template: esempio5-loop.ejs
97
+ // Uso: Passa array "prodotti"
98
+ // URL: http://localhost:3000/esempio5-loop.ejs
99
+
100
+ const esempio5 = async (ctx, next, filePath) => {
101
+ try {
102
+ // Passa un array per il loop
103
+ ctx.body = await ejs.renderFile(filePath, {
104
+ prodotti: ['Laptop', 'Mouse', 'Tastiera', 'Monitor']
105
+ });
106
+ ctx.type = 'text/html';
107
+ } catch (error) {
108
+ console.error('Errore:', error.message);
109
+ ctx.status = 500;
110
+ ctx.body = `<h1>Errore</h1><pre>${error.message}</pre>`;
111
+ }
112
+ };
113
+
114
+ // ============================================================
115
+ // FUNZIONE RENDER UNIVERSALE
116
+ // ============================================================
117
+ // Questa funzione sceglie quale esempio usare in base al file
118
+
119
+ const templateRender = async (ctx, next, filePath) => {
120
+ const fileName = path.basename(filePath);
121
+
122
+ // Sceglie la funzione giusta in base al nome del file
123
+ switch(fileName) {
124
+ case 'esempio1-nessun-dato.ejs':
125
+ return esempio1(ctx, next, filePath);
126
+
127
+ case 'esempio2-una-variabile.ejs':
128
+ return esempio2(ctx, next, filePath);
129
+
130
+ case 'esempio3-piu-variabili.ejs':
131
+ return esempio3(ctx, next, filePath);
132
+
133
+ case 'esempio4-condizionale.ejs':
134
+ return esempio4(ctx, next, filePath);
135
+
136
+ case 'esempio5-loop.ejs':
137
+ return esempio5(ctx, next, filePath);
138
+
139
+ default:
140
+ // Per altri file .ejs, non passa dati
141
+ try {
142
+ ctx.body = await ejs.renderFile(filePath, {});
143
+ ctx.type = 'text/html';
144
+ } catch (error) {
145
+ console.error('Errore:', error.message);
146
+ ctx.status = 500;
147
+ ctx.body = `<h1>Errore</h1><pre>${error.message}</pre>`;
148
+ }
149
+ }
150
+ };
151
+
152
+ // ============================================================
153
+ // CONFIGURAZIONE SERVER
154
+ // ============================================================
155
+
156
+ app.use(
157
+ classicServer(
158
+ __dirname + "/examples",
159
+ {
160
+ showDirContents: true,
161
+ template: {
162
+ render: templateRender,
163
+ ext: ["ejs", "EJS"],
164
+ },
165
+ }
166
+ )
167
+ );
168
+
169
+ app.listen(port, () => {
170
+ console.log("\n" + "=".repeat(60));
171
+ console.log("✅ SERVER AVVIATO");
172
+ console.log("=".repeat(60));
173
+ console.log(`URL: http://localhost:${port}\n`);
174
+
175
+ console.log("📚 ESEMPI DISPONIBILI:");
176
+ console.log("─".repeat(60));
177
+ console.log("1️⃣ Nessun dato:");
178
+ console.log(" http://localhost:3000/esempio1-nessun-dato.ejs");
179
+ console.log("");
180
+ console.log("2️⃣ Una variabile:");
181
+ console.log(" http://localhost:3000/esempio2-una-variabile.ejs");
182
+ console.log("");
183
+ console.log("3️⃣ Più variabili:");
184
+ console.log(" http://localhost:3000/esempio3-piu-variabili.ejs");
185
+ console.log("");
186
+ console.log("4️⃣ Condizionale (if/else):");
187
+ console.log(" http://localhost:3000/esempio4-condizionale.ejs");
188
+ console.log("");
189
+ console.log("5️⃣ Loop (forEach):");
190
+ console.log(" http://localhost:3000/esempio5-loop.ejs");
191
+ console.log("=".repeat(60) + "\n");
192
+ });
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Esempio 1 - Nessun Dato</title>
6
+ </head>
7
+ <body>
8
+ <h1>Ciao Mondo!</h1>
9
+ <p>Questo è un template EJS che non usa nessuna variabile.</p>
10
+ <p>È identico a un normale file HTML.</p>
11
+ </body>
12
+ </html>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Esempio 2 - Una Variabile</title>
6
+ </head>
7
+ <body>
8
+ <h1>Benvenuto!</h1>
9
+ <p>Il tuo nome è: <strong><%= nome %></strong></p>
10
+ </body>
11
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Esempio 3 - Più Variabili</title>
6
+ </head>
7
+ <body>
8
+ <h1>Informazioni</h1>
9
+ <ul>
10
+ <li><strong>Nome:</strong> <%= nome %></li>
11
+ <li><strong>Età:</strong> <%= eta %></li>
12
+ <li><strong>Città:</strong> <%= citta %></li>
13
+ </ul>
14
+ </body>
15
+ </html>
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Esempio 4 - Condizionale</title>
6
+ </head>
7
+ <body>
8
+ <h1>Controllo Accesso</h1>
9
+
10
+ <% if (autenticato) { %>
11
+ <p>✅ Benvenuto <strong><%= nome %></strong>!</p>
12
+ <p>Sei autenticato.</p>
13
+ <% } else { %>
14
+ <p>❌ Non sei autenticato.</p>
15
+ <p>Effettua il login per continuare.</p>
16
+ <% } %>
17
+ </body>
18
+ </html>
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Esempio 5 - Loop</title>
6
+ </head>
7
+ <body>
8
+ <h1>Lista Prodotti</h1>
9
+
10
+ <ul>
11
+ <% prodotti.forEach(function(prodotto) { %>
12
+ <li><%= prodotto %></li>
13
+ <% }); %>
14
+ </ul>
15
+
16
+ <p>Totale: <%= prodotti.length %> prodotti</p>
17
+ </body>
18
+ </html>
@@ -0,0 +1,181 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Esempi Incrementali EJS</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ max-width: 800px;
11
+ margin: 50px auto;
12
+ padding: 20px;
13
+ background: #f5f5f5;
14
+ }
15
+ h1 {
16
+ color: #333;
17
+ border-bottom: 3px solid #007bff;
18
+ padding-bottom: 10px;
19
+ }
20
+ .esempio {
21
+ background: white;
22
+ padding: 20px;
23
+ margin: 20px 0;
24
+ border-radius: 8px;
25
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
26
+ }
27
+ .esempio h2 {
28
+ margin-top: 0;
29
+ color: #007bff;
30
+ }
31
+ .esempio p {
32
+ color: #666;
33
+ margin: 10px 0;
34
+ }
35
+ .esempio code {
36
+ background: #f0f0f0;
37
+ padding: 2px 6px;
38
+ border-radius: 3px;
39
+ font-family: 'Courier New', monospace;
40
+ }
41
+ a.btn {
42
+ display: inline-block;
43
+ padding: 10px 20px;
44
+ background: #007bff;
45
+ color: white;
46
+ text-decoration: none;
47
+ border-radius: 4px;
48
+ margin-top: 10px;
49
+ }
50
+ a.btn:hover {
51
+ background: #0056b3;
52
+ }
53
+ .code-block {
54
+ background: #f8f9fa;
55
+ border-left: 4px solid #007bff;
56
+ padding: 15px;
57
+ margin: 15px 0;
58
+ font-family: 'Courier New', monospace;
59
+ font-size: 14px;
60
+ overflow-x: auto;
61
+ }
62
+ </style>
63
+ </head>
64
+ <body>
65
+ <h1>📚 Esempi Incrementali - Template EJS</h1>
66
+ <p>Questa pagina mostra esempi progressivi di template EJS, partendo dal più semplice al più complesso.</p>
67
+
68
+ <!-- ESEMPIO 1 -->
69
+ <div class="esempio">
70
+ <h2>1️⃣ Esempio 1: Nessun Dato</h2>
71
+ <p>Template EJS senza variabili - equivale a un normale file HTML.</p>
72
+
73
+ <div class="code-block">
74
+ // Server: Non passa nessun dato
75
+ ctx.body = await ejs.renderFile(filePath, {});
76
+
77
+ // Template: Non usa variabili
78
+ &lt;h1&gt;Ciao Mondo!&lt;/h1&gt;
79
+ </div>
80
+
81
+ <a href="/esempio1-nessun-dato.ejs" class="btn">Vedi Esempio 1</a>
82
+ </div>
83
+
84
+ <!-- ESEMPIO 2 -->
85
+ <div class="esempio">
86
+ <h2>2️⃣ Esempio 2: Una Variabile</h2>
87
+ <p>Template che usa <strong>una sola variabile</strong>.</p>
88
+
89
+ <div class="code-block">
90
+ // Server: Passa UNA variabile
91
+ ctx.body = await ejs.renderFile(filePath, {
92
+ nome: 'Mario'
93
+ });
94
+
95
+ // Template: Usa la variabile
96
+ Il tuo nome è: &lt;%= nome %&gt;
97
+ </div>
98
+
99
+ <a href="/esempio2-una-variabile.ejs" class="btn">Vedi Esempio 2</a>
100
+ </div>
101
+
102
+ <!-- ESEMPIO 3 -->
103
+ <div class="esempio">
104
+ <h2>3️⃣ Esempio 3: Più Variabili</h2>
105
+ <p>Template che usa <strong>più variabili</strong>.</p>
106
+
107
+ <div class="code-block">
108
+ // Server: Passa PIÙ variabili
109
+ ctx.body = await ejs.renderFile(filePath, {
110
+ nome: 'Mario',
111
+ eta: 30,
112
+ citta: 'Roma'
113
+ });
114
+
115
+ // Template: Usa tutte le variabili
116
+ Nome: &lt;%= nome %&gt;
117
+ Età: &lt;%= eta %&gt;
118
+ Città: &lt;%= citta %&gt;
119
+ </div>
120
+
121
+ <a href="/esempio3-piu-variabili.ejs" class="btn">Vedi Esempio 3</a>
122
+ </div>
123
+
124
+ <!-- ESEMPIO 4 -->
125
+ <div class="esempio">
126
+ <h2>4️⃣ Esempio 4: Condizionale (if/else)</h2>
127
+ <p>Template con <strong>logica condizionale</strong>.</p>
128
+
129
+ <div class="code-block">
130
+ // Server: Passa variabili per if/else
131
+ ctx.body = await ejs.renderFile(filePath, {
132
+ autenticato: true,
133
+ nome: 'Mario'
134
+ });
135
+
136
+ // Template: Usa if/else
137
+ &lt;% if (autenticato) { %&gt;
138
+ Benvenuto &lt;%= nome %&gt;!
139
+ &lt;% } else { %&gt;
140
+ Non sei autenticato.
141
+ &lt;% } %&gt;
142
+ </div>
143
+
144
+ <a href="/esempio4-condizionale.ejs" class="btn">Vedi Esempio 4</a>
145
+ </div>
146
+
147
+ <!-- ESEMPIO 5 -->
148
+ <div class="esempio">
149
+ <h2>5️⃣ Esempio 5: Loop (forEach)</h2>
150
+ <p>Template con <strong>ciclo forEach</strong> su array.</p>
151
+
152
+ <div class="code-block">
153
+ // Server: Passa un array
154
+ ctx.body = await ejs.renderFile(filePath, {
155
+ prodotti: ['Laptop', 'Mouse', 'Tastiera']
156
+ });
157
+
158
+ // Template: Loop sull'array
159
+ &lt;% prodotti.forEach(function(prodotto) { %&gt;
160
+ &lt;li&gt;&lt;%= prodotto %&gt;&lt;/li&gt;
161
+ &lt;% }); %&gt;
162
+ </div>
163
+
164
+ <a href="/esempio5-loop.ejs" class="btn">Vedi Esempio 5</a>
165
+ </div>
166
+
167
+ <hr style="margin: 40px 0; border: 1px solid #ddd;">
168
+
169
+ <div class="esempio" style="background: #e3f2fd;">
170
+ <h2>💡 Punti Chiave</h2>
171
+ <ul>
172
+ <li><strong>Esempio 1:</strong> Template senza variabili → Non serve passare dati</li>
173
+ <li><strong>Esempio 2:</strong> Template con 1 variabile → Passa 1 dato</li>
174
+ <li><strong>Esempio 3:</strong> Template con N variabili → Passa N dati</li>
175
+ <li><strong>Esempio 4:</strong> Template con if/else → Passa dati per la logica</li>
176
+ <li><strong>Esempio 5:</strong> Template con forEach → Passa array</li>
177
+ </ul>
178
+ <p><strong>Regola:</strong> Devi passare esattamente i dati che il template usa!</p>
179
+ </div>
180
+ </body>
181
+ </html>
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Test koa-classic-server</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ max-width: 800px;
11
+ margin: 50px auto;
12
+ padding: 20px;
13
+ }
14
+ h1 { color: #333; }
15
+ a {
16
+ display: block;
17
+ padding: 10px;
18
+ margin: 10px 0;
19
+ background: #007bff;
20
+ color: white;
21
+ text-decoration: none;
22
+ border-radius: 4px;
23
+ }
24
+ a:hover { background: #0056b3; }
25
+ </style>
26
+ </head>
27
+ <body>
28
+ <h1>Test koa-classic-server</h1>
29
+
30
+ <h2>File Statici</h2>
31
+ <p>✅ Questo è un file HTML statico</p>
32
+
33
+ <h2>Template EJS</h2>
34
+ <a href="/test.ejs">Apri test.ejs (Template EJS)</a>
35
+ <a href="/test.ejs?name=Mario&age=30">test.ejs con query parameters</a>
36
+
37
+ <h2>Directory Listing</h2>
38
+ <a href="/">Torna alla root (directory listing)</a>
39
+ </body>
40
+ </html>
@@ -0,0 +1,64 @@
1
+ <!DOCTYPE html>
2
+ <html lang="it">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title><%= title || 'Test EJS' %></title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ max-width: 800px;
11
+ margin: 50px auto;
12
+ padding: 20px;
13
+ background: #f5f5f5;
14
+ }
15
+ .card {
16
+ background: white;
17
+ padding: 20px;
18
+ border-radius: 8px;
19
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
20
+ margin: 20px 0;
21
+ }
22
+ h1 { color: #333; }
23
+ .info { color: #666; }
24
+ .success { color: green; font-weight: bold; }
25
+ </style>
26
+ </head>
27
+ <body>
28
+ <div class="card">
29
+ <h1>✅ EJS Template Funzionante!</h1>
30
+ <p class="success">Se vedi questo messaggio, il template EJS sta funzionando correttamente.</p>
31
+ </div>
32
+
33
+ <div class="card">
34
+ <h2>📊 Informazioni</h2>
35
+ <p><strong>Titolo:</strong> <%= title %></p>
36
+ <p><strong>User:</strong> <%= user.name %></p>
37
+ <p><strong>Path:</strong> <%= path %></p>
38
+ <p><strong>File Template:</strong> <%= filePath %></p>
39
+ <p><strong>Timestamp:</strong> <%= timestamp %></p>
40
+ </div>
41
+
42
+ <div class="card">
43
+ <h2>🔍 Query Parameters</h2>
44
+ <% if (Object.keys(query).length > 0) { %>
45
+ <ul>
46
+ <% Object.keys(query).forEach(function(key) { %>
47
+ <li><strong><%= key %>:</strong> <%= query[key] %></li>
48
+ <% }); %>
49
+ </ul>
50
+ <% } else { %>
51
+ <p class="info">Nessun parametro query. Prova ad aggiungere ?name=test alla URL</p>
52
+ <% } %>
53
+ </div>
54
+
55
+ <div class="card">
56
+ <h2>📝 Note</h2>
57
+ <ul>
58
+ <li>Questo è un template EJS renderizzato dinamicamente</li>
59
+ <li>I dati vengono passati dalla funzione <code>templateRender</code></li>
60
+ <li>Puoi modificare questo file e ricaricare la pagina</li>
61
+ </ul>
62
+ </div>
63
+ </body>
64
+ </html>