miki-template 2.2.3 → 2.3.1

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 (66) hide show
  1. package/.github/workflows/docs.yml +3 -1
  2. package/.github/workflows/release.yml +0 -5
  3. package/README.md +17 -5
  4. package/benchmarks/ejs-results.json +6 -6
  5. package/benchmarks/ejs.js +5 -3
  6. package/benchmarks/handlebars-results.json +6 -6
  7. package/benchmarks/handlebars.js +5 -8
  8. package/benchmarks/miki-results.json +6 -6
  9. package/benchmarks/miki.js +6 -3
  10. package/benchmarks/pug-results.json +6 -6
  11. package/benchmarks/pug.js +5 -3
  12. package/docs/api/async-render.md +88 -3
  13. package/docs/api/cache.md +90 -3
  14. package/docs/api/compile.md +131 -3
  15. package/docs/api/context-processors.md +80 -3
  16. package/docs/api/filters.md +223 -3
  17. package/docs/api/finder.md +97 -3
  18. package/docs/api/helpers.md +56 -3
  19. package/docs/api/i18n.md +160 -3
  20. package/docs/api/index.md +82 -28
  21. package/docs/api/libraries.md +210 -3
  22. package/docs/api/render-partial.md +84 -3
  23. package/docs/api/render.md +95 -3
  24. package/docs/api/security.md +148 -3
  25. package/docs/api/setup-express.md +78 -2
  26. package/docs/api/tags.md +138 -4
  27. package/docs/filter.md +0 -0
  28. package/docs/guide/advanced-usage.md +403 -6
  29. package/docs/guide/async-rendering.md +312 -4
  30. package/docs/guide/context-processors.md +261 -4
  31. package/docs/guide/custom-filters.md +315 -4
  32. package/docs/guide/custom-tags.md +275 -4
  33. package/docs/guide/filters.md +675 -3
  34. package/docs/guide/getting-started.md +109 -7
  35. package/docs/guide/installation.md +99 -4
  36. package/docs/guide/partial-templates.md +371 -4
  37. package/docs/guide/quick-start.md +228 -6
  38. package/docs/guide/security.md +348 -3
  39. package/docs/guide/tags.md +789 -6
  40. package/docs/guide/template-discovery.md +174 -4
  41. package/docs/guide/template-inheritance.md +277 -4
  42. package/docs/index.md +24 -42
  43. package/docs/integrations/elysia.md +4 -2
  44. package/docs/integrations/express.md +219 -219
  45. package/docs/integrations/fastify.md +4 -2
  46. package/docs/integrations/hono.md +4 -2
  47. package/docs/integrations/index.md +68 -68
  48. package/docs/integrations/koa.md +4 -2
  49. package/docs/integrations/nestjs.md +4 -2
  50. package/docs/integrations/tsed.md +4 -2
  51. package/docs/performance.md +45 -8
  52. package/ex.mjs +1 -1
  53. package/mkdocs.yml +0 -22
  54. package/overrides/main.html +1 -1
  55. package/package.json +1 -1
  56. package/requirements-docs.txt +2 -1
  57. package/src/codegen.js +905 -0
  58. package/src/context.js +42 -30
  59. package/src/filters.js +16 -0
  60. package/src/index.js +66 -61
  61. package/src/tags/control.js +15 -12
  62. package/src/utils.js +60 -0
  63. package/tests/filters.test.js +9 -0
  64. package/docs/javascripts/extra.js +0 -174
  65. package/docs/stylesheets/extra.css +0 -819
  66. package/overrides/partials/footer.html +0 -9
@@ -1,222 +1,444 @@
1
- # Quick Start
1
+ # Quick Start
2
+
3
+
2
4
 
3
5
  A hands-on tour of the most common miki-template workflows. Each example shows **CommonJS** and **ES Modules** side by side — pick the tab that matches your project.
4
6
 
7
+
8
+
5
9
  ## 1. Render a Template String
6
10
 
11
+
12
+
7
13
  The `render()` function compiles and renders in one call. Perfect for email templates, static-site generation, or testing snippets.
8
14
 
15
+
16
+
9
17
  === "CommonJS (require)"
10
18
 
19
+
20
+
11
21
  ```javascript
22
+
12
23
  const { render } = require('miki-template');
13
24
 
25
+
26
+
14
27
  const template = 'Hello {{ user.name|title }}! Roles: {{ user.roles|join:", " }}';
28
+
15
29
  const context = {
30
+
16
31
  user: {
32
+
17
33
  name: 'miki coder',
34
+
18
35
  roles: ['admin', 'developer']
36
+
19
37
  }
38
+
20
39
  };
21
40
 
41
+
42
+
22
43
  const result = render(template, context);
44
+
23
45
  console.log(result);
46
+
24
47
  // Output: "Hello Miki Coder! Roles: admin, developer"
48
+
25
49
  ```
26
50
 
51
+
52
+
27
53
  === "ES Modules (import)"
28
54
 
55
+
56
+
29
57
  ```javascript
58
+
30
59
  import { render } from 'miki-template';
31
60
 
61
+
62
+
32
63
  const template = 'Hello {{ user.name|title }}! Roles: {{ user.roles|join:", " }}';
64
+
33
65
  const context = {
66
+
34
67
  user: {
68
+
35
69
  name: 'miki coder',
70
+
36
71
  roles: ['admin', 'developer']
72
+
37
73
  }
74
+
38
75
  };
39
76
 
77
+
78
+
40
79
  const result = render(template, context);
80
+
41
81
  console.log(result);
82
+
42
83
  // Output: "Hello Miki Coder! Roles: admin, developer"
84
+
43
85
  ```
44
86
 
87
+
88
+
45
89
  ## 2. Compile and Reuse
46
90
 
91
+
92
+
47
93
  When you render the same template many times (e.g. an email template or a partial), use `compile()` to parse it once and reuse the compiled AST across many renders.
48
94
 
95
+
96
+
49
97
  === "CommonJS"
50
98
 
99
+
100
+
51
101
  ```javascript
102
+
52
103
  const { compile } = require('miki-template');
53
104
 
105
+
106
+
54
107
  const template = compile(
108
+
55
109
  '<h1>Hello {{ name|title }}!</h1><p>{{ body|truncatewords:20 }}</p>'
110
+
56
111
  );
57
112
 
113
+
114
+
58
115
  console.log(template.render({ name: 'alice', body: 'A long body of text...' }));
116
+
59
117
  console.log(template.render({ name: 'bob', body: 'Another long body...' }));
118
+
60
119
  ```
61
120
 
121
+
122
+
62
123
  === "ES Modules"
63
124
 
125
+
126
+
64
127
  ```javascript
128
+
65
129
  import { compile } from 'miki-template';
66
130
 
131
+
132
+
67
133
  const template = compile(
134
+
68
135
  '<h1>Hello {{ name|title }}!</h1><p>{{ body|truncatewords:20 }}</p>'
136
+
69
137
  );
70
138
 
139
+
140
+
71
141
  console.log(template.render({ name: 'alice', body: 'A long body of text...' }));
142
+
72
143
  console.log(template.render({ name: 'bob', body: 'Another long body...' }));
144
+
73
145
  ```
74
146
 
147
+
148
+
75
149
  ### Compiled Template Methods
76
150
 
151
+
152
+
77
153
  The object returned by `compile()` exposes several render methods:
78
154
 
155
+
156
+
79
157
  | Method | Description |
158
+
80
159
  |--------|-------------|
160
+
81
161
  | `render(context)` | Synchronous render. |
162
+
82
163
  | `renderWith(context, callOptions)` | Sync render with per-call option overrides (e.g. a different `views` root). |
164
+
83
165
  | `asyncRender(context)` | Async render — awaits Promise-returning helpers/filters. |
166
+
84
167
  | `asyncRenderWith(context, callOptions)` | Async render with per-call option overrides. |
168
+
85
169
  | `renderBlock(blockName, context)` | Render only a single `{% block %}` — ideal for HTMX/AJAX slices. |
170
+
86
171
  | `renderPartial(partialName, context)` | Render only a `{% partialdef %}` block by name. |
87
172
 
173
+
174
+
88
175
  ## 3. Express: Full Page + HTMX Partials
89
176
 
177
+
178
+
90
179
  `setupExpress()` wires everything in one call. After that, `res.render('home')` renders the full template, and `res.render('home#card')` renders only the `card` partial — no extra middleware required.
91
180
 
181
+
182
+
92
183
  === "CommonJS"
93
184
 
185
+
186
+
94
187
  ```javascript
188
+
95
189
  const express = require('express');
190
+
96
191
  const miki = require('miki-template');
97
192
 
193
+
194
+
98
195
  const app = express();
196
+
99
197
  miki.setupExpress(app, { extension: 'html', views: './views' });
100
198
 
199
+
200
+
101
201
  // Full page
202
+
102
203
  app.get('/', (req, res) => res.render('home', { user: req.user }));
103
204
 
205
+
206
+
104
207
  // HTMX / partial response — just append #partialName to the view name
208
+
105
209
  app.get('/partials/:name', (req, res) =>
210
+
106
211
  res.render(`home#${req.params.name}`, { user: req.user })
212
+
107
213
  );
108
214
 
215
+
216
+
109
217
  app.listen(3000);
218
+
110
219
  ```
111
220
 
221
+
222
+
112
223
  === "ES Modules"
113
224
 
225
+
226
+
114
227
  ```javascript
228
+
115
229
  import express from 'express';
230
+
116
231
  import miki from 'miki-template';
117
232
 
233
+
234
+
118
235
  const app = express();
236
+
119
237
  miki.setupExpress(app, { extension: 'html', views: './views' });
120
238
 
239
+
240
+
121
241
  app.get('/', (req, res) => res.render('home', { user: req.user }));
242
+
122
243
  app.get('/partials/:name', (req, res) =>
244
+
123
245
  res.render(`home#${req.params.name}`, { user: req.user })
246
+
124
247
  );
125
248
 
249
+
250
+
126
251
  app.listen(3000);
252
+
127
253
  ```
128
254
 
255
+
256
+
129
257
  ### Manual Express Setup (if you prefer full control)
130
258
 
259
+
260
+
131
261
  === "CommonJS"
132
262
 
263
+
264
+
133
265
  ```javascript
266
+
134
267
  const express = require('express');
268
+
135
269
  const { __express } = require('miki-template');
136
270
 
271
+
272
+
137
273
  const app = express();
274
+
138
275
  app.engine('html', __express);
276
+
139
277
  app.set('view engine', 'html');
278
+
140
279
  app.set('views', './views');
280
+
141
281
  ```
142
282
 
283
+
284
+
143
285
  === "ES Modules"
144
286
 
287
+
288
+
145
289
  ```javascript
290
+
146
291
  import express from 'express';
292
+
147
293
  import { __express } from 'miki-template';
148
294
 
295
+
296
+
149
297
  const app = express();
298
+
150
299
  app.engine('html', __express);
300
+
151
301
  app.set('view engine', 'html');
302
+
152
303
  app.set('views', './views');
304
+
153
305
  ```
154
306
 
307
+
308
+
155
309
  ## 4. Async Rendering
156
310
 
311
+
312
+
157
313
  When your templates use async helpers or async filters, use `asyncRender()` (or `compiled.asyncRender()`).
158
314
 
315
+
316
+
159
317
  === "CommonJS"
160
318
 
319
+
320
+
161
321
  ```javascript
322
+
162
323
  const { asyncRender } = require('miki-template');
163
324
 
325
+
326
+
164
327
  const html = await asyncRender(
328
+
165
329
  'Hello {{ name }} — {{ fetchGreeting user.id }}',
330
+
166
331
  { name: 'World', userId: 42 }
332
+
167
333
  );
334
+
168
335
  ```
169
336
 
337
+
338
+
170
339
  === "ES Modules"
171
340
 
341
+
342
+
172
343
  ```javascript
344
+
173
345
  import { asyncRender } from 'miki-template';
174
346
 
347
+
348
+
175
349
  const html = await asyncRender(
350
+
176
351
  'Hello {{ name }} — {{ fetchGreeting userId }}',
352
+
177
353
  { name: 'World', userId: 42 }
354
+
178
355
  );
356
+
179
357
  ```
180
358
 
359
+
360
+
181
361
  ## 5. Defining and Rendering a Partial
182
362
 
363
+
364
+
183
365
  Partials are reusable template fragments defined with `{% partialdef %}`.
184
366
 
367
+
368
+
185
369
  === "Template (home.html)"
186
370
 
371
+
372
+
187
373
  ```html
374
+
188
375
  {% partialdef card %}
376
+
189
377
  <div class="card">
378
+
190
379
  <h3>{{ title|default:"Untitled" }}</h3>
380
+
191
381
  <p>{{ body|truncatewords:30 }}</p>
382
+
192
383
  </div>
384
+
193
385
  {% endpartialdef %}
194
386
 
387
+
388
+
195
389
  {% partial card with title=entry.title body=entry.body %}
390
+
196
391
  ```
197
392
 
393
+
394
+
198
395
  === "CommonJS"
199
396
 
397
+
398
+
200
399
  ```javascript
400
+
201
401
  const { compile } = require('miki-template');
202
402
 
403
+
404
+
203
405
  const compiled = compile('template string here', { views: './views' });
406
+
204
407
  const html = compiled.renderPartial('card', { title: 'Hi', body: 'World' });
408
+
205
409
  ```
206
410
 
411
+
412
+
207
413
  === "ES Modules"
208
414
 
415
+
416
+
209
417
  ```javascript
418
+
210
419
  import { compile } from 'miki-template';
211
420
 
421
+
422
+
212
423
  const compiled = compile('template string here', { views: './views' });
424
+
213
425
  const html = compiled.renderPartial('card', { title: 'Hi', body: 'World' });
426
+
214
427
  ```
215
428
 
429
+
430
+
216
431
  ## Next Steps
217
432
 
218
- - [Partial Templates](./partial-templates)
219
- - [Template Inheritance](./template-inheritance)
220
- - [Filters](./filters)
221
- - [Tags](./tags)
222
- - [API Reference](../api/)
433
+
434
+
435
+ - [Partial Templates](./partial-templates.md)
436
+
437
+ - [Template Inheritance](./template-inheritance.md)
438
+
439
+ - [Filters](./filters.md)
440
+
441
+ - [Tags](./tags.md)
442
+
443
+ - [API Reference](../api/index.md)
444
+