miki-template 2.2.3 → 2.3.0
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.
- package/.github/workflows/docs.yml +3 -1
- package/.github/workflows/release.yml +0 -5
- package/benchmarks/ejs-results.json +6 -6
- package/benchmarks/ejs.js +5 -3
- package/benchmarks/handlebars-results.json +6 -6
- package/benchmarks/handlebars.js +5 -8
- package/benchmarks/miki-results.json +6 -6
- package/benchmarks/miki.js +6 -3
- package/benchmarks/pug-results.json +6 -6
- package/benchmarks/pug.js +5 -3
- package/docs/api/async-render.md +88 -3
- package/docs/api/cache.md +90 -3
- package/docs/api/compile.md +131 -3
- package/docs/api/context-processors.md +80 -3
- package/docs/api/filters.md +223 -3
- package/docs/api/finder.md +97 -3
- package/docs/api/helpers.md +56 -3
- package/docs/api/i18n.md +160 -3
- package/docs/api/index.md +82 -28
- package/docs/api/libraries.md +210 -3
- package/docs/api/render-partial.md +84 -3
- package/docs/api/render.md +95 -3
- package/docs/api/security.md +148 -3
- package/docs/api/setup-express.md +78 -2
- package/docs/api/tags.md +138 -4
- package/docs/filter.md +0 -0
- package/docs/guide/advanced-usage.md +403 -6
- package/docs/guide/async-rendering.md +312 -4
- package/docs/guide/context-processors.md +261 -4
- package/docs/guide/custom-filters.md +315 -4
- package/docs/guide/custom-tags.md +275 -4
- package/docs/guide/filters.md +675 -3
- package/docs/guide/getting-started.md +109 -7
- package/docs/guide/installation.md +99 -4
- package/docs/guide/partial-templates.md +371 -4
- package/docs/guide/quick-start.md +228 -6
- package/docs/guide/security.md +348 -3
- package/docs/guide/tags.md +789 -6
- package/docs/guide/template-discovery.md +174 -4
- package/docs/guide/template-inheritance.md +277 -4
- package/docs/index.md +24 -42
- package/docs/integrations/elysia.md +4 -2
- package/docs/integrations/express.md +219 -219
- package/docs/integrations/fastify.md +4 -2
- package/docs/integrations/hono.md +4 -2
- package/docs/integrations/index.md +68 -68
- package/docs/integrations/koa.md +4 -2
- package/docs/integrations/nestjs.md +4 -2
- package/docs/integrations/tsed.md +4 -2
- package/docs/performance.md +45 -8
- package/ex.mjs +1 -1
- package/mkdocs.yml +0 -22
- package/overrides/main.html +1 -1
- package/package.json +1 -1
- package/requirements-docs.txt +2 -1
- package/src/codegen.js +905 -0
- package/src/context.js +42 -30
- package/src/filters.js +16 -0
- package/src/index.js +66 -61
- package/src/tags/control.js +15 -12
- package/src/utils.js +60 -0
- package/tests/filters.test.js +9 -0
- package/docs/javascripts/extra.js +0 -174
- package/docs/stylesheets/extra.css +0 -819
- 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
|
-
|
|
219
|
-
|
|
220
|
-
- [
|
|
221
|
-
|
|
222
|
-
- [
|
|
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
|
+
|