miki-template 2.3.1 → 2.3.3

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 (167) hide show
  1. package/README.md +1 -1
  2. package/package.json +24 -2
  3. package/src/codegen.js +140 -9
  4. package/src/parser.js +69 -1
  5. package/src/tags/control.js +112 -51
  6. package/src/tags/extra.js +4 -17
  7. package/src/tags/i18n.js +6 -17
  8. package/src/tags/inheritance.js +6 -20
  9. package/src/tags/util.js +5 -20
  10. package/.eslintrc.json +0 -16
  11. package/.github/release-notes/v1.3.1.md +0 -55
  12. package/.github/release-notes/v1.3.3.md +0 -77
  13. package/.github/release-notes/v1.3.7.md +0 -20
  14. package/.github/workflows/ci.yml +0 -42
  15. package/.github/workflows/docs.yml +0 -107
  16. package/.github/workflows/release.yml +0 -107
  17. package/AGENT.md +0 -71
  18. package/API_REFERENCE.md +0 -341
  19. package/CHANGELOG.md +0 -173
  20. package/CODE_OF_CONDUCT.md +0 -14
  21. package/CONTRIBUTING.md +0 -27
  22. package/ROADMAP.md +0 -40
  23. package/assets/banner.png +0 -0
  24. package/assets/logo.png +0 -0
  25. package/benchmarks/ejs-results.json +0 -17
  26. package/benchmarks/ejs.js +0 -38
  27. package/benchmarks/handlebars-results.json +0 -17
  28. package/benchmarks/handlebars.js +0 -45
  29. package/benchmarks/miki-results.json +0 -17
  30. package/benchmarks/miki.js +0 -39
  31. package/benchmarks/pug-results.json +0 -17
  32. package/benchmarks/pug.js +0 -38
  33. package/benchmarks/report.json +0 -17
  34. package/benchmarks/run.js +0 -81
  35. package/benchmarks/stress.mjs +0 -647
  36. package/benchmarks/templates/large.dtpl +0 -7
  37. package/benchmarks/templates/medium.dtpl +0 -3
  38. package/benchmarks/templates/small.dtpl +0 -7
  39. package/context/component.md +0 -109
  40. package/context/prd.md +0 -131
  41. package/context/project-structure.md +0 -33
  42. package/dir/base.html +0 -23
  43. package/dir/cmpnt.html +0 -11
  44. package/dir/footer.html +0 -3
  45. package/dir/home.html +0 -80
  46. package/dir/index.html +0 -80
  47. package/dir/navbar.html +0 -9
  48. package/docs/api/async-render.md +0 -170
  49. package/docs/api/cache.md +0 -174
  50. package/docs/api/compile.md +0 -256
  51. package/docs/api/context-processors.md +0 -154
  52. package/docs/api/filters.md +0 -437
  53. package/docs/api/finder.md +0 -188
  54. package/docs/api/helpers.md +0 -106
  55. package/docs/api/i18n.md +0 -314
  56. package/docs/api/index.md +0 -108
  57. package/docs/api/libraries.md +0 -414
  58. package/docs/api/render-partial.md +0 -162
  59. package/docs/api/render.md +0 -184
  60. package/docs/api/security.md +0 -290
  61. package/docs/api/setup-express.md +0 -152
  62. package/docs/api/tags.md +0 -268
  63. package/docs/assets/banner.png +0 -0
  64. package/docs/assets/logo.png +0 -0
  65. package/docs/filter.md +0 -0
  66. package/docs/guide/advanced-usage.md +0 -794
  67. package/docs/guide/async-rendering.md +0 -616
  68. package/docs/guide/context-processors.md +0 -514
  69. package/docs/guide/custom-filters.md +0 -622
  70. package/docs/guide/custom-tags.md +0 -542
  71. package/docs/guide/filters.md +0 -1314
  72. package/docs/guide/getting-started.md +0 -204
  73. package/docs/guide/installation.md +0 -190
  74. package/docs/guide/partial-templates.md +0 -734
  75. package/docs/guide/quick-start.md +0 -444
  76. package/docs/guide/security.md +0 -690
  77. package/docs/guide/tags.md +0 -1566
  78. package/docs/guide/template-discovery.md +0 -340
  79. package/docs/guide/template-inheritance.md +0 -546
  80. package/docs/guide/what-is-miki-template.md +0 -28
  81. package/docs/guide/why-miki-template.md +0 -75
  82. package/docs/index.md +0 -86
  83. package/docs/integrations/elysia.md +0 -80
  84. package/docs/integrations/express.md +0 -219
  85. package/docs/integrations/fastify.md +0 -79
  86. package/docs/integrations/hono.md +0 -80
  87. package/docs/integrations/index.md +0 -68
  88. package/docs/integrations/koa.md +0 -90
  89. package/docs/integrations/nestjs.md +0 -80
  90. package/docs/integrations/tsed.md +0 -83
  91. package/docs/performance.md +0 -74
  92. package/eslint.config.mjs +0 -42
  93. package/ex.mjs +0 -36
  94. package/live-test/integrations/elysia-example.js +0 -16
  95. package/live-test/integrations/express-example.js +0 -24
  96. package/live-test/integrations/fastify-example.js +0 -20
  97. package/live-test/integrations/hono-example.js +0 -16
  98. package/live-test/integrations/koa-example.js +0 -30
  99. package/live-test/integrations/nestjs-example.js +0 -25
  100. package/live-test/integrations/smoke-test.js +0 -166
  101. package/live-test/integrations/tsed-example.js +0 -23
  102. package/live-test/package-lock.json +0 -1150
  103. package/live-test/package.json +0 -13
  104. package/live-test/packages/product/templates/product/detail.html +0 -7
  105. package/live-test/server.js +0 -38
  106. package/live-test/templates/app_templates/detail.html +0 -6
  107. package/live-test/views/base.html +0 -8
  108. package/live-test/views/child.html +0 -7
  109. package/live-test/views/home.html +0 -17
  110. package/live-test/views/index.html +0 -1
  111. package/miki-template-extension/.github/workflows/ci.yml +0 -116
  112. package/miki-template-extension/.vscodeignore +0 -7
  113. package/miki-template-extension/CHANGELOG.md +0 -99
  114. package/miki-template-extension/LICENSE +0 -21
  115. package/miki-template-extension/README.md +0 -273
  116. package/miki-template-extension/extension.js +0 -1013
  117. package/miki-template-extension/icon.png +0 -0
  118. package/miki-template-extension/icon.svg +0 -10
  119. package/miki-template-extension/miki-template-1.7.1.vsix +0 -0
  120. package/miki-template-extension/package.json +0 -280
  121. package/miki-template-extension/snippets/miki-template.json +0 -717
  122. package/miki-template-extension/syntaxes/language-configuration.json +0 -114
  123. package/miki-template-extension/syntaxes/miki-template.tmLanguage.json +0 -355
  124. package/miki-template-extension/tests/grammar-tests.json +0 -162
  125. package/miki-template-extension/tests/run-grammar-tests.js +0 -82
  126. package/mkdocs.yml +0 -195
  127. package/overrides/main.html +0 -26
  128. package/requirements-docs.txt +0 -2
  129. package/sample-app/package-lock.json +0 -901
  130. package/sample-app/package.json +0 -9
  131. package/sample-app/server.js +0 -14
  132. package/sample-app/views/index.html +0 -1
  133. package/scripts/build-vsix.js +0 -129
  134. package/scripts/build-vsix.ps1 +0 -15
  135. package/snippets/miki-template.json +0 -177
  136. package/src/asyncRender.js +0 -21
  137. package/src/types.d.ts +0 -107
  138. package/syntaxes/language-configuration.json +0 -26
  139. package/syntaxes/miki-template.tmLanguage.json +0 -146
  140. package/tests/asyncRender.test.js +0 -17
  141. package/tests/base.html +0 -6
  142. package/tests/child.html +0 -3
  143. package/tests/context_processors.test.js +0 -13
  144. package/tests/esm.test.mjs +0 -61
  145. package/tests/filters.test.js +0 -263
  146. package/tests/finder-appdirs.test.js +0 -19
  147. package/tests/finder.test.js +0 -17
  148. package/tests/fixtures/views/nested/index.html +0 -1
  149. package/tests/fixtures/views/partial.html +0 -1
  150. package/tests/fixtures/views/sub/deepfile.html +0 -1
  151. package/tests/fixtures/views-appdirs/product/site/detail.html +0 -1
  152. package/tests/include_security.test.js +0 -9
  153. package/tests/integration/README.md +0 -32
  154. package/tests/integration/features.test.cjs +0 -1681
  155. package/tests/integration/features.test.mjs +0 -1697
  156. package/tests/integration/finder.esm.test.mjs +0 -13
  157. package/tests/integration/partial-render.test.cjs +0 -13
  158. package/tests/integration/templates/base.miki +0 -6
  159. package/tests/integration/templates/child.miki +0 -6
  160. package/tests/integration/templates/index.html +0 -17
  161. package/tests/lexer.test.js +0 -45
  162. package/tests/parser.test.js +0 -57
  163. package/tests/partial.html +0 -1
  164. package/tests/partialdef.test.js +0 -79
  165. package/tests/production_checks.js +0 -57
  166. package/tests/security.test.js +0 -28
  167. 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