miki-template 2.3.1 → 2.3.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 (159) hide show
  1. package/package.json +45 -1
  2. package/.eslintrc.json +0 -16
  3. package/.github/release-notes/v1.3.1.md +0 -55
  4. package/.github/release-notes/v1.3.3.md +0 -77
  5. package/.github/release-notes/v1.3.7.md +0 -20
  6. package/.github/workflows/ci.yml +0 -42
  7. package/.github/workflows/docs.yml +0 -107
  8. package/.github/workflows/release.yml +0 -107
  9. package/AGENT.md +0 -71
  10. package/API_REFERENCE.md +0 -341
  11. package/CHANGELOG.md +0 -173
  12. package/CODE_OF_CONDUCT.md +0 -14
  13. package/CONTRIBUTING.md +0 -27
  14. package/ROADMAP.md +0 -40
  15. package/assets/banner.png +0 -0
  16. package/assets/logo.png +0 -0
  17. package/benchmarks/ejs-results.json +0 -17
  18. package/benchmarks/ejs.js +0 -38
  19. package/benchmarks/handlebars-results.json +0 -17
  20. package/benchmarks/handlebars.js +0 -45
  21. package/benchmarks/miki-results.json +0 -17
  22. package/benchmarks/miki.js +0 -39
  23. package/benchmarks/pug-results.json +0 -17
  24. package/benchmarks/pug.js +0 -38
  25. package/benchmarks/report.json +0 -17
  26. package/benchmarks/run.js +0 -81
  27. package/benchmarks/stress.mjs +0 -647
  28. package/benchmarks/templates/large.dtpl +0 -7
  29. package/benchmarks/templates/medium.dtpl +0 -3
  30. package/benchmarks/templates/small.dtpl +0 -7
  31. package/context/component.md +0 -109
  32. package/context/prd.md +0 -131
  33. package/context/project-structure.md +0 -33
  34. package/dir/base.html +0 -23
  35. package/dir/cmpnt.html +0 -11
  36. package/dir/footer.html +0 -3
  37. package/dir/home.html +0 -80
  38. package/dir/index.html +0 -80
  39. package/dir/navbar.html +0 -9
  40. package/docs/api/async-render.md +0 -170
  41. package/docs/api/cache.md +0 -174
  42. package/docs/api/compile.md +0 -256
  43. package/docs/api/context-processors.md +0 -154
  44. package/docs/api/filters.md +0 -437
  45. package/docs/api/finder.md +0 -188
  46. package/docs/api/helpers.md +0 -106
  47. package/docs/api/i18n.md +0 -314
  48. package/docs/api/index.md +0 -108
  49. package/docs/api/libraries.md +0 -414
  50. package/docs/api/render-partial.md +0 -162
  51. package/docs/api/render.md +0 -184
  52. package/docs/api/security.md +0 -290
  53. package/docs/api/setup-express.md +0 -152
  54. package/docs/api/tags.md +0 -268
  55. package/docs/assets/banner.png +0 -0
  56. package/docs/assets/logo.png +0 -0
  57. package/docs/filter.md +0 -0
  58. package/docs/guide/advanced-usage.md +0 -794
  59. package/docs/guide/async-rendering.md +0 -616
  60. package/docs/guide/context-processors.md +0 -514
  61. package/docs/guide/custom-filters.md +0 -622
  62. package/docs/guide/custom-tags.md +0 -542
  63. package/docs/guide/filters.md +0 -1314
  64. package/docs/guide/getting-started.md +0 -204
  65. package/docs/guide/installation.md +0 -190
  66. package/docs/guide/partial-templates.md +0 -734
  67. package/docs/guide/quick-start.md +0 -444
  68. package/docs/guide/security.md +0 -690
  69. package/docs/guide/tags.md +0 -1566
  70. package/docs/guide/template-discovery.md +0 -340
  71. package/docs/guide/template-inheritance.md +0 -546
  72. package/docs/guide/what-is-miki-template.md +0 -28
  73. package/docs/guide/why-miki-template.md +0 -75
  74. package/docs/index.md +0 -86
  75. package/docs/integrations/elysia.md +0 -80
  76. package/docs/integrations/express.md +0 -219
  77. package/docs/integrations/fastify.md +0 -79
  78. package/docs/integrations/hono.md +0 -80
  79. package/docs/integrations/index.md +0 -68
  80. package/docs/integrations/koa.md +0 -90
  81. package/docs/integrations/nestjs.md +0 -80
  82. package/docs/integrations/tsed.md +0 -83
  83. package/docs/performance.md +0 -74
  84. package/eslint.config.mjs +0 -42
  85. package/ex.mjs +0 -36
  86. package/live-test/integrations/elysia-example.js +0 -16
  87. package/live-test/integrations/express-example.js +0 -24
  88. package/live-test/integrations/fastify-example.js +0 -20
  89. package/live-test/integrations/hono-example.js +0 -16
  90. package/live-test/integrations/koa-example.js +0 -30
  91. package/live-test/integrations/nestjs-example.js +0 -25
  92. package/live-test/integrations/smoke-test.js +0 -166
  93. package/live-test/integrations/tsed-example.js +0 -23
  94. package/live-test/package-lock.json +0 -1150
  95. package/live-test/package.json +0 -13
  96. package/live-test/packages/product/templates/product/detail.html +0 -7
  97. package/live-test/server.js +0 -38
  98. package/live-test/templates/app_templates/detail.html +0 -6
  99. package/live-test/views/base.html +0 -8
  100. package/live-test/views/child.html +0 -7
  101. package/live-test/views/home.html +0 -17
  102. package/live-test/views/index.html +0 -1
  103. package/miki-template-extension/.github/workflows/ci.yml +0 -116
  104. package/miki-template-extension/.vscodeignore +0 -7
  105. package/miki-template-extension/CHANGELOG.md +0 -99
  106. package/miki-template-extension/LICENSE +0 -21
  107. package/miki-template-extension/README.md +0 -273
  108. package/miki-template-extension/extension.js +0 -1013
  109. package/miki-template-extension/icon.png +0 -0
  110. package/miki-template-extension/icon.svg +0 -10
  111. package/miki-template-extension/miki-template-1.7.1.vsix +0 -0
  112. package/miki-template-extension/package.json +0 -280
  113. package/miki-template-extension/snippets/miki-template.json +0 -717
  114. package/miki-template-extension/syntaxes/language-configuration.json +0 -114
  115. package/miki-template-extension/syntaxes/miki-template.tmLanguage.json +0 -355
  116. package/miki-template-extension/tests/grammar-tests.json +0 -162
  117. package/miki-template-extension/tests/run-grammar-tests.js +0 -82
  118. package/mkdocs.yml +0 -195
  119. package/overrides/main.html +0 -26
  120. package/requirements-docs.txt +0 -2
  121. package/sample-app/package-lock.json +0 -901
  122. package/sample-app/package.json +0 -9
  123. package/sample-app/server.js +0 -14
  124. package/sample-app/views/index.html +0 -1
  125. package/scripts/build-vsix.js +0 -129
  126. package/scripts/build-vsix.ps1 +0 -15
  127. package/snippets/miki-template.json +0 -177
  128. package/src/asyncRender.js +0 -21
  129. package/src/types.d.ts +0 -107
  130. package/syntaxes/language-configuration.json +0 -26
  131. package/syntaxes/miki-template.tmLanguage.json +0 -146
  132. package/tests/asyncRender.test.js +0 -17
  133. package/tests/base.html +0 -6
  134. package/tests/child.html +0 -3
  135. package/tests/context_processors.test.js +0 -13
  136. package/tests/esm.test.mjs +0 -61
  137. package/tests/filters.test.js +0 -263
  138. package/tests/finder-appdirs.test.js +0 -19
  139. package/tests/finder.test.js +0 -17
  140. package/tests/fixtures/views/nested/index.html +0 -1
  141. package/tests/fixtures/views/partial.html +0 -1
  142. package/tests/fixtures/views/sub/deepfile.html +0 -1
  143. package/tests/fixtures/views-appdirs/product/site/detail.html +0 -1
  144. package/tests/include_security.test.js +0 -9
  145. package/tests/integration/README.md +0 -32
  146. package/tests/integration/features.test.cjs +0 -1681
  147. package/tests/integration/features.test.mjs +0 -1697
  148. package/tests/integration/finder.esm.test.mjs +0 -13
  149. package/tests/integration/partial-render.test.cjs +0 -13
  150. package/tests/integration/templates/base.miki +0 -6
  151. package/tests/integration/templates/child.miki +0 -6
  152. package/tests/integration/templates/index.html +0 -17
  153. package/tests/lexer.test.js +0 -45
  154. package/tests/parser.test.js +0 -57
  155. package/tests/partial.html +0 -1
  156. package/tests/partialdef.test.js +0 -79
  157. package/tests/production_checks.js +0 -57
  158. package/tests/security.test.js +0 -28
  159. package/tests/tags.test.js +0 -233
@@ -1,546 +0,0 @@
1
- # Template Inheritance
2
-
3
-
4
-
5
- miki-template supports Django-style template inheritance via `{% extends %}` and `{% block %}`. This lets you build layout hierarchies where child templates override parent blocks.
6
-
7
-
8
-
9
- ## Table of Contents
10
-
11
-
12
-
13
- - [Basic Inheritance](#basic-inheritance)
14
-
15
- - [block.super](#blocksuper)
16
-
17
- - [Multi-Level Inheritance](#multi-level-inheritance)
18
-
19
- - [Rendering a Single Block](#rendering-a-single-block)
20
-
21
- - [block Default Behavior](#block-default-behavior)
22
-
23
- - [Path Traversal Protection](#path-traversal-protection)
24
-
25
- - [Smart Template Discovery for Inheritance](#smart-template-discovery-for-inheritance)
26
-
27
-
28
-
29
- ---
30
-
31
-
32
-
33
- ## Basic Inheritance
34
-
35
-
36
-
37
- ### base.html
38
-
39
-
40
-
41
- ```html
42
-
43
- <!DOCTYPE html>
44
-
45
- <html>
46
-
47
- <head>
48
-
49
- <title>{% block title %}Default Title{% endblock %}</title>
50
-
51
- </head>
52
-
53
- <body>
54
-
55
- <header>{% block header %}Default Header{% endblock %}</header>
56
-
57
- <main>{% block content %}Default Content{% endblock %}</main>
58
-
59
- <footer>{% block footer %}Default Footer{% endblock %}</footer>
60
-
61
- </body>
62
-
63
- </html>
64
-
65
- ```
66
-
67
-
68
-
69
- ### child.html
70
-
71
-
72
-
73
- ```html
74
-
75
- {% extends "base.html" %}
76
-
77
-
78
-
79
- {% block title %}My Page{% endblock %}
80
-
81
-
82
-
83
- {% block content %}
84
-
85
- <h1>Hello, {{ user.name }}!</h1>
86
-
87
- {% for item in items %}
88
-
89
- <p>{{ item }}</p>
90
-
91
- {% endfor %}
92
-
93
- {% endblock %}
94
-
95
- ```
96
-
97
-
98
-
99
- **Key behaviors:**
100
-
101
-
102
-
103
- - The child template's text outside `{% block %}` tags is **ignored** — only the blocks are used to override the parent.
104
-
105
- - Any blocks not overridden in the child use the parent's default content.
106
-
107
- - The parent is located using the `views` option (or Express's `views` directory).
108
-
109
-
110
-
111
- ## block.super
112
-
113
-
114
-
115
- Inside a block, `{{ block.super }}` renders the parent template's version of that block. This is useful for augmentation rather than replacement.
116
-
117
-
118
-
119
- === "Example"
120
-
121
-
122
-
123
- ```html
124
-
125
- {% extends "base.html" %}
126
-
127
-
128
-
129
- {% block content %}
130
-
131
- <h1>My Content</h1>
132
-
133
- {{ block.super }}
134
-
135
- {% endblock %}
136
-
137
- ```
138
-
139
-
140
-
141
- If `base.html`'s content block is `<p>Original</p>`, the output is:
142
-
143
-
144
-
145
- ```html
146
-
147
- <h1>My Content</h1>
148
-
149
- <p>Original</p>
150
-
151
- ```
152
-
153
-
154
-
155
- **Real-world sidebar that adds to the parent:**
156
-
157
-
158
-
159
- ```html
160
-
161
- <!-- base.html -->
162
-
163
- {% block sidebar %}
164
-
165
- <ul class="nav">
166
-
167
- <li><a href="/">Home</a></li>
168
-
169
- </ul>
170
-
171
- {% endblock %}
172
-
173
-
174
-
175
- <!-- admin.html -->
176
-
177
- {% extends "base.html" %}
178
-
179
- {% block sidebar %}
180
-
181
- {{ block.super }}
182
-
183
- <li><a href="/admin">Admin Panel</a></li>
184
-
185
- {% endblock %}
186
-
187
- ```
188
-
189
-
190
-
191
- ## Multi-Level Inheritance
192
-
193
-
194
-
195
- Inheritance chains can be arbitrarily deep:
196
-
197
-
198
-
199
- ```text
200
-
201
- base.html
202
-
203
- └── child.html
204
-
205
- └── grandchild.html
206
-
207
- ```
208
-
209
-
210
-
211
- Each level can override blocks from its parent, and `{{ block.super }}` traverses the chain correctly.
212
-
213
-
214
-
215
- ### Three-level example
216
-
217
-
218
-
219
- **base.html:**
220
-
221
-
222
-
223
- ```html
224
-
225
- <html>
226
-
227
- <body>
228
-
229
- {% block content %}Base content{% endblock %}
230
-
231
- </body>
232
-
233
- </html>
234
-
235
- ```
236
-
237
-
238
-
239
- **child.html:**
240
-
241
-
242
-
243
- ```html
244
-
245
- {% extends "base.html" %}
246
-
247
-
248
-
249
- {% block content %}
250
-
251
- <h2>Child content</h2>
252
-
253
- {{ block.super }}
254
-
255
- {% endblock %}
256
-
257
- ```
258
-
259
-
260
-
261
- **grandchild.html:**
262
-
263
-
264
-
265
- ```html
266
-
267
- {% extends "child.html" %}
268
-
269
-
270
-
271
- {% block content %}
272
-
273
- <h1>Grandchild content</h1>
274
-
275
- {{ block.super }}
276
-
277
- {% endblock %}
278
-
279
- ```
280
-
281
-
282
-
283
- Rendering `grandchild.html` produces:
284
-
285
-
286
-
287
- ```html
288
-
289
- <html>
290
-
291
- <body>
292
-
293
- <h1>Grandchild content</h1>
294
-
295
- <h2>Child content</h2>
296
-
297
- Base content
298
-
299
- </body>
300
-
301
- </html>
302
-
303
- ```
304
-
305
-
306
-
307
- ## Rendering a Single Block
308
-
309
-
310
-
311
- Compile a template and render only one block — useful for AJAX or HTMX responses where you only need a portion of the page:
312
-
313
-
314
-
315
- === "CommonJS"
316
-
317
-
318
-
319
- ```javascript
320
-
321
- const { compile } = require('miki-template');
322
-
323
-
324
-
325
- const compiled = compile(childTemplateStr, { views: './templates' });
326
-
327
- const partialHtml = compiled.renderBlock('content', context);
328
-
329
- ```
330
-
331
-
332
-
333
- === "ES Modules"
334
-
335
-
336
-
337
- ```javascript
338
-
339
- import { compile } from 'miki-template';
340
-
341
-
342
-
343
- const compiled = compile(childTemplateStr, { views: './templates' });
344
-
345
- const partialHtml = compiled.renderBlock('content', context);
346
-
347
- ```
348
-
349
-
350
-
351
- ### renderBlock behavior
352
-
353
-
354
-
355
- - If the block is not found, throws `Block 'blockName' not found in template`.
356
-
357
- - If the block has no overrides, renders the default body.
358
-
359
- - If the block has overrides, renders the child-most block first, then traverses up for `{{ block.super }}`.
360
-
361
-
362
-
363
- **Real-world HTMX use case:**
364
-
365
-
366
-
367
- ```html
368
-
369
- <!-- layout.html -->
370
-
371
- {% block main %}
372
-
373
- <div id="main-content">
374
-
375
- <!-- default content -->
376
-
377
- </div>
378
-
379
- {% endblock %}
380
-
381
- ```
382
-
383
-
384
-
385
- ```javascript
386
-
387
- // Return only the main block for an AJAX update
388
-
389
- app.get('/ajax/content', (req, res) => {
390
-
391
- const compiled = miki.compile(template, { views: './views' });
392
-
393
- res.send(compiled.renderBlock('main', { user: req.user }));
394
-
395
- });
396
-
397
- ```
398
-
399
-
400
-
401
- ## block Default Behavior
402
-
403
-
404
-
405
- If a child template does not override a block, the parent's default content is rendered:
406
-
407
-
408
-
409
- ```html
410
-
411
- <!-- base.html -->
412
-
413
- <html>
414
-
415
- <body>
416
-
417
- {% block sidebar %}Default sidebar{% endblock %}
418
-
419
- </body>
420
-
421
- </html>
422
-
423
- ```
424
-
425
-
426
-
427
- ```html
428
-
429
- <!-- child.html -->
430
-
431
- {% extends "base.html" %}
432
-
433
-
434
-
435
- {% block content %}Main content{% endblock %}
436
-
437
- <!-- sidebar block is not overridden, so "Default sidebar" is used -->
438
-
439
- ```
440
-
441
-
442
-
443
- ## Dynamic extends
444
-
445
-
446
-
447
- You can use expressions in `extends` for device-specific or conditional layouts:
448
-
449
-
450
-
451
- ```html
452
-
453
- {% extends device_type|default:"base.html" %}
454
-
455
- ```
456
-
457
-
458
-
459
- ```html
460
-
461
- {% extends user.theme|default:"default.html" %}
462
-
463
- ```
464
-
465
-
466
-
467
- ## Path Traversal Protection
468
-
469
-
470
-
471
- `{% extends %}` and `{% include %}` paths are validated to prevent directory traversal attacks:
472
-
473
-
474
-
475
- ```html
476
-
477
- {% extends "../../etc/passwd" %} {# REJECTED #}
478
-
479
- {% include "../../secrets" %} {# REJECTED #}
480
-
481
- ```
482
-
483
-
484
-
485
- The engine checks that resolved paths stay within the allowed views directories. An `Error` with message starting `path traversal` is thrown if a path escapes the views root.
486
-
487
-
488
-
489
- ## Smart Template Discovery for Inheritance
490
-
491
-
492
-
493
- When using `setupExpress()`, the engine automatically searches for parent templates in:
494
-
495
-
496
-
497
- - The configured `views` directory
498
-
499
- - Nested `templates/` directories inside the views root
500
-
501
- - Subdirectories of the views root
502
-
503
- - App-style `app/templates/...`, `packages/*/templates/...`, etc.
504
-
505
-
506
-
507
- This means you can organize templates like:
508
-
509
-
510
-
511
- ```text
512
-
513
- project/
514
-
515
- ├── views/
516
-
517
- │ ├── base.html
518
-
519
- │ └── home.html
520
-
521
- ├── app/
522
-
523
- │ └── templates/
524
-
525
- │ └── admin/
526
-
527
- │ └── dashboard.html
528
-
529
- ```
530
-
531
-
532
-
533
- And `{% extends "base.html" %}` will be found regardless of where the child template lives.
534
-
535
-
536
-
537
- ## Next Steps
538
-
539
-
540
-
541
- - [Partial Templates](./partial-templates.md)
542
-
543
- - [Tags: extends and block](./tags.md#inheritance-tags)
544
-
545
- - [Template Discovery](./template-discovery.md)
546
-
@@ -1,28 +0,0 @@
1
- # What is miki-template?
2
-
3
- miki-template is a **Django-style template engine for Node.js and Express**. It brings Django's beloved template language — variables, filters, tags, inheritance, and partials — to the Node.js ecosystem with first-class Express integration and modern JavaScript support.
4
-
5
- ## Philosophy
6
-
7
- miki-template is designed for developers who love Django's template syntax but want the speed and flexibility of Node.js. It prioritizes:
8
-
9
- - **Developer experience**: Familiar Django syntax, excellent error messages, and sensible defaults.
10
- - **Performance**: Compiled AST rendering that scales to large, real-world templates.
11
- - **Modern Node.js**: Full ESM and CommonJS support, async rendering, and compatibility with current Express/Koa/Fastify/Hono/Elysia versions.
12
- - **Security**: Auto-escaping, safe strings, and Django-style security primitives built in.
13
-
14
- ## Key Concepts
15
-
16
- - **Templates** are text files using `{{ variables }}`, `{% tags %}`, and `| filters`.
17
- - **Partials** let you define reusable components with `{% partialdef %}` and render them by name.
18
- - **Template inheritance** uses `{% extends %}` and `{% block %}` to build layout hierarchies.
19
- - **Smart discovery** finds templates across `views/`, `app/templates/`, and nested folders automatically.
20
-
21
- ## Who is it for?
22
-
23
- miki-template is a great fit if you:
24
-
25
- - Prefer Django-style templates over JSX or pure string concatenation.
26
- - Need **partial rendering** for HTMX or AJAX-heavy apps.
27
- - Want a template engine that **scales** without rewriting templates as your app grows.
28
- - Value **security** and want XSS protection by default.
@@ -1,75 +0,0 @@
1
- # Why miki-template?
2
-
3
- There are plenty of template engines for Node.js. Here is why miki-template stands out.
4
-
5
- ## Django Syntax You Already Know
6
-
7
- If you have used Django, you already know miki-template. The syntax is intentionally aligned:
8
-
9
- ```html
10
- {% if user.is_admin %}
11
- <p>Welcome, {{ user.name|title }}!</p>
12
- {% elif user.is_staff %}
13
- <p>Staff dashboard</p>
14
- {% else %}
15
- <p>Please log in.</p>
16
- {% endif %}
17
- ```
18
-
19
- No new DSL to learn. No context switching between backend and frontend templating styles.
20
-
21
- ## Built for HTMX and Partial Responses
22
-
23
- Modern web apps increasingly use HTMX, Turbo, or custom AJAX. miki-template makes partial rendering trivial:
24
-
25
- ```javascript
26
- app.get('/card/:id', (req, res) =>
27
- res.render(`home#card`, { title: 'Hello', body: '...' })
28
- );
29
- ```
30
-
31
- No extra middleware. No manual view resolution. Just `view#partial`.
32
-
33
- ## Smart Template Discovery
34
-
35
- Forget `Failed to lookup view` errors. miki-template searches your project structure intelligently:
36
-
37
- - `views/`
38
- - `app/templates/`
39
- - `packages/*/templates/`
40
- - Any custom folder name you configure
41
-
42
- This mirrors Django's `APP_DIRS` behavior and means templates can live where they make sense in your codebase.
43
-
44
- ## Performance That Scales
45
-
46
- miki-template's compiled AST approach is especially fast on realistic templates — the ones with loops, conditionals, filters, and partials that make up real pages.
47
-
48
- | Template | miki-template | pug | handlebars | ejs |
49
- |----------|--------------|-----|------------|-----|
50
- | Small | ~115k rps | 1.7M rps | 417k rps | 182k rps |
51
- | Medium | ~454k rps | 625k rps | 48k rps | 29k rps |
52
- | Large | **~476k rps** | 3.1k rps | 661 rps | 290 rps |
53
-
54
- On large templates, miki-template is **~150× faster** than pug, handlebars, and ejs.
55
-
56
- ## Security by Default
57
-
58
- - Auto-escaping enabled by default.
59
- - SafeString wrapper for explicit bypass.
60
- - CSRF and CSP tags included.
61
- - No `eval()` or unsafe code execution.
62
-
63
- ## First-Class Express Integration
64
-
65
- One function wires everything:
66
-
67
- ```javascript
68
- miki.setupExpress(app, { extension: 'html', views: './views' });
69
- ```
70
-
71
- That is it. No `app.engine()` boilerplate. No manual `res.render` patching. Partial responses work out of the box.
72
-
73
- ## Extensible and Future-Proof
74
-
75
- Need a custom tag? A custom filter? The API is clean and well-documented. miki-template is built to grow with your app, not lock you into a fragile abstraction.
package/docs/index.md DELETED
@@ -1,86 +0,0 @@
1
- # miki-template
2
-
3
- Django-style template magic for Node.js — blazing fast partials, smart template discovery, and zero friction for HTMX.
4
- miki comes with more tags and filters that are not in django/jinja and miki templates supports all django tags and filters plus it own additional tags and filters.
5
- you can register your own custom filters and filters in miki templates.
6
-
7
- miki is secure and production ready with active maintainer and performance improvements.
8
-
9
- [Get Started](guide/quick-start.md) | [API Reference](api/index.md) | [GitHub](https://github.com/alainmiki/miki-template)
10
-
11
- ![miki-template banner](assets/banner.png)
12
-
13
- ## Why miki-template?
14
-
15
- miki-template brings Django's beloved template language to Node.js and Express. Define reusable partials with `{% partialdef %}`, render any slice of a page with `render('home#card')`, and let the engine find templates across your whole project — `templates/`, `app/templates/`, or whatever structure you prefer.
16
-
17
- - **Partial-powered templating**: `{% partialdef %}` blocks render by name anywhere — `res.render('home#card')`, `renderPartialFromSource(...)`, or `compiled.renderBlock('block')`. Built for HTMX-style partial responses.
18
- - **Smart template discovery**: Stop hardcoding view paths. The engine searches `templates/`, nested app directories, and custom folder names automatically — just like Django.
19
- - **One-line Express integration**: `miki.setupExpress(app, { extension: 'html', views: dir })` wires everything up. No boilerplate, no extra middleware.
20
- - **Full Django syntax parity**: Variables, dotted lookups, filters (`|`), block tags (`{% %}`), template inheritance with `extends` and `block.super`.
21
- - **Blazing fast**: Compiled AST rendering dominates on realistic pages — ~150× faster than pug, handlebars, and ejs on large templates.
22
- - **ESM & CommonJS**: Works seamlessly with both `import` and `require` syntax.
23
- - **Security by default**: Auto-escaping, `SafeString`, CSRF and CSP tags.
24
-
25
- ## Quick example
26
-
27
- === "CommonJS"
28
-
29
- ```javascript
30
- const express = require('express');
31
- const miki = require('miki-template');
32
-
33
- const app = express();
34
- miki.setupExpress(app, { extension: 'html', views: './views' });
35
-
36
- app.get('/', (req, res) => res.render('home', { user: req.user }));
37
- app.get('/partials/:name', (req, res) =>
38
- res.render(`home#${req.params.name}`, { user: req.user })
39
- );
40
-
41
- app.listen(3000);
42
- ```
43
-
44
- === "ES Modules"
45
-
46
- ```javascript
47
- import express from 'express';
48
- import miki from 'miki-template';
49
-
50
- const app = express();
51
- miki.setupExpress(app, { extension: 'html', views: './views' });
52
-
53
- app.get('/', (req, res) => res.render('home', { user: req.user }));
54
- app.get('/partials/:name', (req, res) =>
55
- res.render(`home#${req.params.name}`, { user: req.user })
56
- );
57
-
58
- app.listen(3000);
59
- ```
60
-
61
- ## Installation
62
-
63
- ```bash
64
- npm install miki-template
65
- ```
66
-
67
- See the [Installation guide](guide/installation.md) for pnpm, yarn, and Bun instructions.
68
-
69
- ## Documentation
70
-
71
- - [What is miki-template?](guide/what-is-miki-template.md)
72
- - [Getting Started](guide/getting-started.md)
73
- - [Quick Start](guide/quick-start.md)
74
- - [Filters](guide/filters.md)
75
- - [Tags](guide/tags.md)
76
- - [Partial Templates](guide/partial-templates.md)
77
- - [Template Inheritance](guide/template-inheritance.md)
78
- - [Template Discovery](guide/template-discovery.md)
79
- - [Security](guide/security.md)
80
- - [Integrations](integrations/index.md)
81
- - [API Reference](api/index.md)
82
- - [Performance](performance.md)
83
-
84
- ## License
85
-
86
- MIT