mikel 0.22.2 → 0.24.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/README.md +36 -20
- package/index.d.ts +3 -3
- package/index.js +25 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -360,6 +360,16 @@ The `escape` helper allows to escape the provided block content.
|
|
|
360
360
|
console.log(m("{{#escape}}<b>Hello World!</b>{{/escape}}")); // --> '<b>Hello World!</b>
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
+
#### raw
|
|
364
|
+
|
|
365
|
+
> Added in `v0.23.0`.
|
|
366
|
+
|
|
367
|
+
The `raw` helper allows to render the content of the block without evaluating it. All the stuff inside the block will be rendered as is, without processing any variables or helpers.
|
|
368
|
+
|
|
369
|
+
```javascript
|
|
370
|
+
console.log(m("{{#raw}}Hello {{name}}!{{/raw}}", {name: "Bob"})); // --> 'Hello {{name}}!'
|
|
371
|
+
```
|
|
372
|
+
|
|
363
373
|
### Custom Helpers
|
|
364
374
|
|
|
365
375
|
> Added in `v0.5.0`.
|
|
@@ -610,83 +620,89 @@ const result = mikel("Hello, {{name}}!", data);
|
|
|
610
620
|
console.log(result); // Output: "Hello, World!"
|
|
611
621
|
```
|
|
612
622
|
|
|
613
|
-
### `mikel.create(
|
|
623
|
+
### `mikel.create(options)`
|
|
624
|
+
|
|
625
|
+
> Removed `template` argument in `v0.24.0`.
|
|
614
626
|
|
|
615
|
-
Allows to create an isolated instance of mikel, useful when you want to
|
|
627
|
+
Allows to create an isolated instance of mikel, useful when you want to use the same options for multiple templates without passing them every time. You can pass an `options` object with the same structure as the one used in the `mikel` function, which will be used for all templates compiled with this instance.
|
|
616
628
|
|
|
617
|
-
It returns a function that you can call with the data to compile the template.
|
|
629
|
+
It returns a function that you can call with the template and data to compile the template.
|
|
618
630
|
|
|
619
631
|
```javascript
|
|
620
632
|
import mikel from "mikel";
|
|
621
633
|
|
|
622
|
-
const
|
|
634
|
+
const mk = mikel.create({
|
|
635
|
+
partials: {
|
|
636
|
+
hello: "Hello, {{name}}!",
|
|
637
|
+
},
|
|
638
|
+
});
|
|
623
639
|
|
|
624
|
-
console.log(
|
|
625
|
-
console.log(
|
|
640
|
+
console.log(mk("{{>hello}}", {name: "Bob"})); // --> "Hello, Bob!"
|
|
641
|
+
console.log(mk("{{>hello}}", {name: "Susan"})); // --> "Hello, Susan!"
|
|
626
642
|
```
|
|
627
643
|
|
|
628
644
|
It also exposes the following additional methods:
|
|
629
645
|
|
|
630
|
-
#### `
|
|
646
|
+
#### `mk.use(options)`
|
|
631
647
|
|
|
632
648
|
> Added in `v0.19.0`.
|
|
633
649
|
|
|
634
650
|
Allows to extend the templating with custom **helpers**, **functions**, and **partials**.
|
|
635
651
|
|
|
636
652
|
```javascript
|
|
637
|
-
|
|
653
|
+
mk.use({
|
|
638
654
|
partials: {
|
|
639
655
|
foo: "bar",
|
|
640
656
|
},
|
|
641
657
|
});
|
|
642
658
|
```
|
|
643
659
|
|
|
644
|
-
#### `
|
|
660
|
+
#### `mk.addHelper(helperName, helperFn)`
|
|
645
661
|
|
|
646
662
|
Allows to register a new helper instead of using the `options` object.
|
|
647
663
|
|
|
648
664
|
```javascript
|
|
649
|
-
|
|
665
|
+
mk.addHelper("foo", () => { ... });
|
|
650
666
|
```
|
|
651
667
|
|
|
652
|
-
#### `
|
|
668
|
+
#### `mk.removeHelper(helperName)`
|
|
653
669
|
|
|
654
670
|
Removes a previously added helper.
|
|
655
671
|
|
|
656
672
|
```javascript
|
|
657
|
-
|
|
673
|
+
mk.removeHelper("foo");
|
|
658
674
|
```
|
|
659
675
|
|
|
660
|
-
#### `
|
|
676
|
+
#### `mk.addPartial(partialName, partialCode)`
|
|
661
677
|
|
|
662
678
|
Registers a new partial instead of using the `options` object.
|
|
663
679
|
|
|
664
680
|
```javascript
|
|
665
|
-
|
|
681
|
+
mk.addPartial("bar", " ... ");
|
|
666
682
|
```
|
|
667
683
|
|
|
668
|
-
#### `
|
|
684
|
+
#### `mk.removePartial(partialName)`
|
|
669
685
|
|
|
670
686
|
Removes a previously added partial.
|
|
671
687
|
|
|
672
688
|
```javascript
|
|
673
|
-
|
|
689
|
+
mk.removePartial("bar");
|
|
674
690
|
```
|
|
675
691
|
|
|
676
|
-
#### `
|
|
692
|
+
#### `mk.addFunction(fnName, fn)`
|
|
677
693
|
|
|
678
694
|
Registers a new function instead of using the `options` object.
|
|
679
695
|
|
|
680
696
|
```javascript
|
|
681
|
-
|
|
697
|
+
mk.addFunction("foo", () => "...");
|
|
682
698
|
```
|
|
683
699
|
|
|
684
|
-
#### `
|
|
700
|
+
#### `mk.removeFunction(fnName)`
|
|
685
701
|
|
|
686
702
|
Removes a previously added function.
|
|
687
703
|
|
|
688
704
|
```javascript
|
|
689
|
-
|
|
705
|
+
mk.removeFunction("foo");
|
|
690
706
|
```
|
|
691
707
|
|
|
692
708
|
### `mikel.escape(str)`
|
package/index.d.ts
CHANGED
|
@@ -33,8 +33,8 @@ declare interface MikelOptions {
|
|
|
33
33
|
variables?: Variables;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
declare interface
|
|
37
|
-
(data?: any): string;
|
|
36
|
+
declare interface MikelInstance {
|
|
37
|
+
(template: string, data?: any): string;
|
|
38
38
|
use(options: Partial<MikelOptions>): MikelTemplate;
|
|
39
39
|
addHelper(name: string, fn: HelperFunction): void;
|
|
40
40
|
removeHelper(name: string): void;
|
|
@@ -46,7 +46,7 @@ declare interface MikelTemplate {
|
|
|
46
46
|
|
|
47
47
|
declare const mikel: {
|
|
48
48
|
(template: string, data?: any, options?: Partial<MikelOptions>): string;
|
|
49
|
-
create(
|
|
49
|
+
create(options?: Partial<MikelOptions>): MikelInstance;
|
|
50
50
|
escape(str: string): string;
|
|
51
51
|
get(context: any, path: string): any;
|
|
52
52
|
parse(value: string, context?: any, vars?: any): any;
|
package/index.js
CHANGED
|
@@ -13,7 +13,7 @@ const get = (c, p) => (p === "." ? c : p.split(".").reduce((x, k) => x?.[k], c))
|
|
|
13
13
|
// @description tokenize and untokenize methods
|
|
14
14
|
const tokenize = (str = "") => str.split(/\{\{|\}\}/);
|
|
15
15
|
const untokenize = (ts = [], s = "{{", e = "}}") => {
|
|
16
|
-
return ts.reduce((p, t, i) => p + (i % 2 === 0 ? e : s) + t);
|
|
16
|
+
return ts.length > 0 ? ts.reduce((p, t, i) => p + (i % 2 === 0 ? e : s) + t) : "";
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
// @description parse string arguments
|
|
@@ -45,6 +45,22 @@ const parse = (v, data = {}, vars = {}) => {
|
|
|
45
45
|
return (v || "").startsWith("@") ? get(vars, v.slice(1)) : get(data, v || ".");
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
// @description find the index of the closing token
|
|
49
|
+
const findClosingToken = (tokens, i, token) => {
|
|
50
|
+
while(i < tokens.length) {
|
|
51
|
+
if (i % 2 > 0) {
|
|
52
|
+
if (tokens[i].startsWith("/") && tokens[i].slice(1).trim() === token) {
|
|
53
|
+
return i;
|
|
54
|
+
}
|
|
55
|
+
else if (tokens[i].startsWith("#") && tokens[i].slice(1).trim().split(" ")[0] === token) {
|
|
56
|
+
i = findClosingToken(tokens, i + 1, token);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
i = i + 1;
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Unmatched section end: {{${token}}}`);
|
|
62
|
+
};
|
|
63
|
+
|
|
48
64
|
// @description default helpers
|
|
49
65
|
const defaultHelpers = {
|
|
50
66
|
"each": p => {
|
|
@@ -60,12 +76,12 @@ const defaultHelpers = {
|
|
|
60
76
|
"ne": p => p.args[0] !== p.args[1] ? p.fn(p.data) : "",
|
|
61
77
|
"with": p => p.fn(p.args[0]),
|
|
62
78
|
"escape": p => escape(p.fn(p.data)),
|
|
79
|
+
"raw": p => untokenize(p.tokens),
|
|
63
80
|
};
|
|
64
81
|
|
|
65
82
|
// @description create a new instance of mikel
|
|
66
|
-
const create = (
|
|
83
|
+
const create = (options = {}) => {
|
|
67
84
|
const ctx = {
|
|
68
|
-
tokens: tokenize(template),
|
|
69
85
|
helpers: Object.assign({}, defaultHelpers, options?.helpers || {}),
|
|
70
86
|
partials: Object.assign({}, options?.partials || {}),
|
|
71
87
|
functions: options?.functions || {},
|
|
@@ -81,20 +97,18 @@ const create = (template = "", options = {}) => {
|
|
|
81
97
|
else if (tokens[i].startsWith("#") && typeof ctx.helpers[tokens[i].slice(1).trim().split(" ")[0]] === "function") {
|
|
82
98
|
const [t, args, opt] = parseArgs(tokens[i].slice(1), data, vars);
|
|
83
99
|
const j = i + 1;
|
|
100
|
+
i = findClosingToken(tokens, j, t);
|
|
84
101
|
output.push(ctx.helpers[t]({
|
|
85
102
|
args: args,
|
|
86
103
|
opt: opt,
|
|
104
|
+
tokens: tokens.slice(j, i),
|
|
87
105
|
data: data,
|
|
88
106
|
variables: vars,
|
|
89
107
|
fn: (blockData = {}, blockVars = {}, blockOutput = []) => {
|
|
90
|
-
|
|
108
|
+
compile(tokens, blockOutput, blockData, {...vars, ...blockVars, parent: data, root: vars.root}, j, t);
|
|
91
109
|
return blockOutput.join("");
|
|
92
110
|
},
|
|
93
111
|
}));
|
|
94
|
-
// Make sure that this block is executed at least once
|
|
95
|
-
if (i + 1 === j) {
|
|
96
|
-
i = compile(tokens, [], {}, {}, j, t);
|
|
97
|
-
}
|
|
98
112
|
}
|
|
99
113
|
else if (tokens[i].startsWith("#") || tokens[i].startsWith("^")) {
|
|
100
114
|
const t = tokens[i].slice(1).trim();
|
|
@@ -155,8 +169,8 @@ const create = (template = "", options = {}) => {
|
|
|
155
169
|
return i;
|
|
156
170
|
};
|
|
157
171
|
// entry method to compile the template with the provided data object
|
|
158
|
-
const compileTemplate = (data = {}, output = []) => {
|
|
159
|
-
compile(
|
|
172
|
+
const compileTemplate = (template, data = {}, output = []) => {
|
|
173
|
+
compile(tokenize(template), output, data, {root: data, ...ctx.variables}, 0, "");
|
|
160
174
|
return output.join("");
|
|
161
175
|
};
|
|
162
176
|
// assign api methods and return method to compile the template
|
|
@@ -183,7 +197,7 @@ const create = (template = "", options = {}) => {
|
|
|
183
197
|
|
|
184
198
|
// @description main compiler function
|
|
185
199
|
const mikel = (template = "", data = {}, options = {}) => {
|
|
186
|
-
return create(template,
|
|
200
|
+
return create(options)(template, data);
|
|
187
201
|
};
|
|
188
202
|
|
|
189
203
|
// @description assign utilities
|