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,794 +0,0 @@
1
- # Advanced Usage
2
-
3
-
4
-
5
- This guide covers advanced miki-template features: caching, library system, i18n, and more.
6
-
7
-
8
-
9
- ## Table of Contents
10
-
11
-
12
-
13
- - [Caching](#caching)
14
-
15
- - [Library System](#library-system)
16
-
17
- - [i18n / Internationalization](#i18n--internationalization)
18
-
19
- - [Template Discovery](#template-discovery)
20
-
21
- - [Partial Templates](#partial-templates)
22
-
23
- - [Extending the Engine](#extending-the-engine)
24
-
25
-
26
-
27
- ---
28
-
29
-
30
-
31
- ## Caching
32
-
33
-
34
-
35
- miki-template caches compiled templates for performance. The cache is an in-memory LRU with a 100-entry limit.
36
-
37
-
38
-
39
- ### Clearing the Cache
40
-
41
-
42
-
43
- === "CommonJS"
44
-
45
-
46
-
47
- ```javascript
48
-
49
- const { clearCache } = require('miki-template');
50
-
51
-
52
-
53
- clearCache();
54
-
55
- ```
56
-
57
-
58
-
59
- === "ES Modules"
60
-
61
-
62
-
63
- ```javascript
64
-
65
- import { clearCache } from 'miki-template';
66
-
67
-
68
-
69
- clearCache();
70
-
71
- ```
72
-
73
-
74
-
75
- ### When to Clear Cache
76
-
77
-
78
-
79
- - **Development** — when templates change frequently on disk
80
-
81
- - **Tests** — to ensure fresh compilation
82
-
83
- - **Runtime filter/tag registration** — when dynamically registering custom tags/filters
84
-
85
-
86
-
87
- ```javascript
88
-
89
- // Development middleware that clears cache on file changes
90
-
91
- const { clearCache } = require('miki-template');
92
-
93
-
94
-
95
- if (process.env.NODE_ENV !== 'production') {
96
-
97
- fs.watch('./views', () => {
98
-
99
- clearCache();
100
-
101
- console.log('Template cache cleared');
102
-
103
- });
104
-
105
- }
106
-
107
- ```
108
-
109
-
110
-
111
- ### How Caching Works
112
-
113
-
114
-
115
- - Templates are cached by source string and compile options.
116
-
117
- - The cache key combines the template source and the options object (views, custom settings).
118
-
119
- - Cached templates are reused across renders, improving performance for repeated templates.
120
-
121
-
122
-
123
- ## Library System
124
-
125
-
126
-
127
- Libraries are bundles of filters, tags, and helpers that can be loaded into templates. Built-in libraries (humanize, cache, lorem, markdown, i18n) are auto-activated.
128
-
129
-
130
-
131
- ### Registering a Library
132
-
133
-
134
-
135
- === "CommonJS"
136
-
137
-
138
-
139
- ```javascript
140
-
141
- const { registerLibrary } = require('miki-template');
142
-
143
-
144
-
145
- registerLibrary('myutils', {
146
-
147
- filters: {
148
-
149
- shout: (val) => String(val).toUpperCase() + '!',
150
-
151
- whisper: (val) => String(val).toLowerCase() + '...'
152
-
153
- },
154
-
155
- tags: {
156
-
157
- timestamp: (tagContent, parser) => ({
158
-
159
- render: () => new Date().toISOString()
160
-
161
- })
162
-
163
- },
164
-
165
- helpers: {
166
-
167
- formatPrice: (val) => `$${Number(val).toFixed(2)}`
168
-
169
- }
170
-
171
- });
172
-
173
- ```
174
-
175
-
176
-
177
- === "ES Modules"
178
-
179
-
180
-
181
- ```javascript
182
-
183
- import { registerLibrary } from 'miki-template';
184
-
185
-
186
-
187
- registerLibrary('myutils', {
188
-
189
- filters: {
190
-
191
- shout: (val) => String(val).toUpperCase() + '!',
192
-
193
- whisper: (val) => String(val).toLowerCase() + '...'
194
-
195
- },
196
-
197
- tags: {
198
-
199
- timestamp: (tagContent, parser) => ({
200
-
201
- render: () => new Date().toISOString()
202
-
203
- })
204
-
205
- },
206
-
207
- helpers: {
208
-
209
- formatPrice: (val) => `$${Number(val).toFixed(2)}`
210
-
211
- }
212
-
213
- });
214
-
215
- ```
216
-
217
-
218
-
219
- ### Loading Libraries in Templates
220
-
221
-
222
-
223
- Once registered, load the library with `{% load %}`:
224
-
225
-
226
-
227
- ```html
228
-
229
- {% load myutils %}
230
-
231
-
232
-
233
- {{ price|formatPrice }}
234
-
235
- {{ message|shout }}
236
-
237
- {% timestamp %}
238
-
239
- ```
240
-
241
-
242
-
243
- ### Built-in Libraries
244
-
245
-
246
-
247
- The following libraries are auto-activated (no `{% load %}` needed):
248
-
249
-
250
-
251
- | Library | Features |
252
-
253
- |---------|----------|
254
-
255
- | `humanize` | Natural date formatting, number formatting |
256
-
257
- | `cache` | Cache control tags and filters |
258
-
259
- | `lorem` | Lorem ipsum placeholder text |
260
-
261
- | `markdown` | `{{ content|markdown }}` filter for Markdown→HTML |
262
-
263
- | `i18n` | `{% trans %}` and `{% blocktrans %}` for translations |
264
-
265
-
266
-
267
- ### Deactivating and Re-registering
268
-
269
-
270
-
271
- === "CommonJS"
272
-
273
-
274
-
275
- ```javascript
276
-
277
- const { unregisterLibrary, activateLibrary } = require('miki-template');
278
-
279
-
280
-
281
- // Remove a library
282
-
283
- unregisterLibrary('lorem');
284
-
285
-
286
-
287
- // Re-activate
288
-
289
- activateLibrary('lorem');
290
-
291
- ```
292
-
293
-
294
-
295
- === "ES Modules"
296
-
297
-
298
-
299
- ```javascript
300
-
301
- import { unregisterLibrary, activateLibrary } from 'miki-template';
302
-
303
-
304
-
305
- unregisterLibrary('lorem');
306
-
307
- activateLibrary('lorem');
308
-
309
- ```
310
-
311
-
312
-
313
- ## i18n / Internationalization
314
-
315
-
316
-
317
- miki-template includes a built-in i18n system supporting `{% trans %}` and `{% blocktrans %}` tags.
318
-
319
-
320
-
321
- ### Registering Translations
322
-
323
-
324
-
325
- === "CommonJS"
326
-
327
-
328
-
329
- ```javascript
330
-
331
- const miki = require('miki-template');
332
-
333
-
334
-
335
- miki.setLanguage('fr');
336
-
337
- miki.registerTranslation('fr', {
338
-
339
- 'Hello': 'Bonjour',
340
-
341
- 'Goodbye': 'Au revoir',
342
-
343
- 'Welcome, {name}!': 'Bienvenue, {name} !'
344
-
345
- });
346
-
347
- ```
348
-
349
-
350
-
351
- === "ES Modules"
352
-
353
-
354
-
355
- ```javascript
356
-
357
- import { setLanguage, registerTranslation } from 'miki-template';
358
-
359
-
360
-
361
- setLanguage('fr');
362
-
363
- registerTranslation('fr', {
364
-
365
- 'Hello': 'Bonjour',
366
-
367
- 'Goodbye': 'Au revoir',
368
-
369
- 'Welcome, {name}!': 'Bienvenue, {name} !'
370
-
371
- });
372
-
373
- ```
374
-
375
-
376
-
377
- ### Setting Fallback Language
378
-
379
-
380
-
381
- === "CommonJS"
382
-
383
-
384
-
385
- ```javascript
386
-
387
- const { setLanguage, setFallbackLanguage } = require('miki-template');
388
-
389
-
390
-
391
- setLanguage('fr');
392
-
393
- setFallbackLanguage('en');
394
-
395
- ```
396
-
397
-
398
-
399
- === "ES Modules"
400
-
401
-
402
-
403
- ```javascript
404
-
405
- import { setLanguage, setFallbackLanguage } from 'miki-template';
406
-
407
-
408
-
409
- setLanguage('fr');
410
-
411
- setFallbackLanguage('en');
412
-
413
- ```
414
-
415
-
416
-
417
- ### Template Usage
418
-
419
-
420
-
421
- ```html
422
-
423
- {% trans "Hello" %}
424
-
425
- {% blocktrans %}Welcome, {{ name }}!{% endblocktrans %}
426
-
427
- ```
428
-
429
-
430
-
431
- ### Managing Languages
432
-
433
-
434
-
435
- === "CommonJS"
436
-
437
-
438
-
439
- ```javascript
440
-
441
- const {
442
-
443
- registerTranslation,
444
-
445
- unregisterTranslation,
446
-
447
- setLanguage,
448
-
449
- getLanguage,
450
-
451
- setFallbackLanguage,
452
-
453
- getFallbackLanguage,
454
-
455
- getAvailableLanguages
456
-
457
- } = require('miki-template');
458
-
459
- ```
460
-
461
-
462
-
463
- === "ES Modules"
464
-
465
-
466
-
467
- ```javascript
468
-
469
- import {
470
-
471
- registerTranslation,
472
-
473
- unregisterTranslation,
474
-
475
- setLanguage,
476
-
477
- getLanguage,
478
-
479
- setFallbackLanguage,
480
-
481
- getFallbackLanguage,
482
-
483
- getAvailableLanguages
484
-
485
- } from 'miki-template';
486
-
487
- ```
488
-
489
-
490
-
491
- ## Template Discovery
492
-
493
-
494
-
495
- The `findTemplateInViews()` function intelligently locates templates in nested directories.
496
-
497
-
498
-
499
- === "CommonJS"
500
-
501
-
502
-
503
- ```javascript
504
-
505
- const { findTemplateInViews, setAppTemplateDirNames } = require('miki-template');
506
-
507
-
508
-
509
- // Customize which directory names are treated as app template roots
510
-
511
- setAppTemplateDirNames(['templates', 'views', 'pages']);
512
-
513
-
514
-
515
- // Search for a template by name
516
-
517
- const found = findTemplateInViews('home', ['./views', './app/templates']);
518
-
519
- console.log(found);
520
-
521
- // → /absolute/path/to/app/templates/home.html
522
-
523
- ```
524
-
525
-
526
-
527
- === "ES Modules"
528
-
529
-
530
-
531
- ```javascript
532
-
533
- import { findTemplateInViews, setAppTemplateDirNames } from 'miki-template';
534
-
535
-
536
-
537
- setAppTemplateDirNames(['templates', 'views', 'pages']);
538
-
539
- const found = findTemplateInViews('home', ['./views', './app/templates']);
540
-
541
- console.log(found);
542
-
543
- ```
544
-
545
-
546
-
547
- ## Partial Templates
548
-
549
-
550
-
551
- Partials let you define reusable template fragments using `{% partialdef %}` and render them on demand.
552
-
553
-
554
-
555
- ### Defining and Rendering Partials
556
-
557
-
558
-
559
- ```html
560
-
561
- {% partialdef card %}
562
-
563
- <div class="card">
564
-
565
- <h3>{{ user.name }}</h3>
566
-
567
- <p>{{ user.email }}</p>
568
-
569
- </div>
570
-
571
- {% endpartialdef %}
572
-
573
- ```
574
-
575
-
576
-
577
- Render a partial:
578
-
579
-
580
-
581
- === "CommonJS"
582
-
583
-
584
-
585
- ```javascript
586
-
587
- const { render, compile } = require('miki-template');
588
-
589
-
590
-
591
- // Using render() with file partials:
592
-
593
- const html = render('home#card', { user: userData }, { views: './views' });
594
-
595
-
596
-
597
- // Using compiled.renderPartial():
598
-
599
- const compiled = compile(templateString);
600
-
601
- const partialHtml = compiled.renderPartial('card', { user: userData });
602
-
603
- ```
604
-
605
-
606
-
607
- === "ES Modules"
608
-
609
-
610
-
611
- ```javascript
612
-
613
- import { render, compile } from 'miki-template';
614
-
615
-
616
-
617
- const html = render('home#card', { user: userData }, { views: './views' });
618
-
619
-
620
-
621
- const compiled = compile(templateString);
622
-
623
- const partialHtml = compiled.renderPartial('card', { user: userData });
624
-
625
- ```
626
-
627
-
628
-
629
- ### Partial with Context
630
-
631
-
632
-
633
- ```html
634
-
635
- {% partialdef greeting %}
636
-
637
- Hello, {{ name }}! You have {{ count }} messages.
638
-
639
- {% endpartialdef %}
640
-
641
-
642
-
643
- {% partial greeting with name="Alice" count=3 %}
644
-
645
- ```
646
-
647
-
648
-
649
- ## Extending the Engine
650
-
651
-
652
-
653
- ### Registering Custom Tags
654
-
655
-
656
-
657
- === "CommonJS"
658
-
659
-
660
-
661
- ```javascript
662
-
663
- const { registerTag } = require('miki-template');
664
-
665
-
666
-
667
- registerTag('markdown', (tagContent, parser) => {
668
-
669
- const nodelist = parser.parse(['endmarkdown']);
670
-
671
- parser.skipTag();
672
-
673
- const { marked } = require('marked');
674
-
675
-
676
-
677
- return {
678
-
679
- render: (context) => {
680
-
681
- const body = nodelist.map(n => n.render(context)).join('');
682
-
683
- return markSafe(marked(body));
684
-
685
- }
686
-
687
- };
688
-
689
- });
690
-
691
- ```
692
-
693
-
694
-
695
- === "ES Modules"
696
-
697
-
698
-
699
- ```javascript
700
-
701
- import { registerTag, markSafe } from 'miki-template';
702
-
703
- import { marked } from 'marked';
704
-
705
-
706
-
707
- registerTag('markdown', (tagContent, parser) => {
708
-
709
- const nodelist = parser.parse(['endmarkdown']);
710
-
711
- parser.skipTag();
712
-
713
-
714
-
715
- return {
716
-
717
- render: (context) => {
718
-
719
- const body = nodelist.map(n => n.render(context)).join('');
720
-
721
- return markSafe(marked(body));
722
-
723
- }
724
-
725
- };
726
-
727
- });
728
-
729
- ```
730
-
731
-
732
-
733
- ### Registering Custom Helpers
734
-
735
-
736
-
737
- === "CommonJS"
738
-
739
-
740
-
741
- ```javascript
742
-
743
- const { registerHelper } = require('miki-template');
744
-
745
-
746
-
747
- registerHelper('truncate_words', (str, count) => {
748
-
749
- const words = String(str).split(/\s+/);
750
-
751
- return words.slice(0, count).join(' ') + (words.length > count ? '...' : '');
752
-
753
- });
754
-
755
- ```
756
-
757
-
758
-
759
- === "ES Modules"
760
-
761
-
762
-
763
- ```javascript
764
-
765
- import { registerHelper } from 'miki-template';
766
-
767
-
768
-
769
- registerHelper('truncate_words', (str, count) => {
770
-
771
- const words = String(str).split(/\s+/);
772
-
773
- return words.slice(0, count).join(' ') + (words.length > count ? '...' : '');
774
-
775
- });
776
-
777
- ```
778
-
779
-
780
-
781
- ## Next Steps
782
-
783
-
784
-
785
- - [Custom Tags](./custom-tags.md)
786
-
787
- - [Custom Filters](./custom-filters.md)
788
-
789
- - [API Reference: Libraries](../api/libraries.md)
790
-
791
- - [API Reference: Cache](../api/cache.md)
792
-
793
- - [API Reference: i18n](../api/i18n.md)
794
-