mikel 0.5.0 → 0.7.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 +34 -6
- package/index.js +28 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -234,11 +234,11 @@ Custom helper functions receive a single object parameter containing the followi
|
|
|
234
234
|
|
|
235
235
|
The helper function must return a string, which will be injected into the result string.
|
|
236
236
|
|
|
237
|
-
### Variables
|
|
237
|
+
### Runtime Variables
|
|
238
238
|
|
|
239
239
|
> Added in `v0.4.0`.
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
Runtime Variables in Mikel provide convenient access to special values within your templates. These variables, denoted by the `@` symbol, allow users to interact with specific data contexts or values at runtime. Runtime variables are usually generated by helpers like `#each`.
|
|
242
242
|
|
|
243
243
|
#### @root
|
|
244
244
|
|
|
@@ -266,7 +266,27 @@ The `@key` variable allows users to retrieve the current key of the object entry
|
|
|
266
266
|
|
|
267
267
|
The `@value` variable allows users to retrieve the current value of the object entry when iterating over an object using the `#each` helper. It simplifies access to object values for dynamic rendering and data manipulation.
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
#### @first
|
|
270
|
+
|
|
271
|
+
> Added in `v0.7.0`.
|
|
272
|
+
|
|
273
|
+
The `@first` variable allows to check if the current iteration using the `#each` helper is the first item in the array or object.
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
{{#each items}} {{.}}: {{#if @first}}first item!{{/if}}{{#unless @first}}not first{{/if}} {{/each}}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### @last
|
|
280
|
+
|
|
281
|
+
> Added in `v0.7.0`.
|
|
282
|
+
|
|
283
|
+
The `@last` variable allows to check if the current iteration using the `#each` helper is the last item in the array or object.
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
{{#each items}}{{@index}}:{{.}} {{#unless @last}},{{/unless}}{{/each}}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Custom runtime variables
|
|
270
290
|
|
|
271
291
|
> Added in `v0.5.0`
|
|
272
292
|
|
|
@@ -289,7 +309,7 @@ In this example, the custom data variable `customVariable` is defined with the v
|
|
|
289
309
|
|
|
290
310
|
## API
|
|
291
311
|
|
|
292
|
-
### `
|
|
312
|
+
### `mikel(template, data[, options])`
|
|
293
313
|
|
|
294
314
|
Render the given template string with the provided data object.
|
|
295
315
|
|
|
@@ -303,16 +323,24 @@ Render the given template string with the provided data object.
|
|
|
303
323
|
Returns: A string with the rendered output.
|
|
304
324
|
|
|
305
325
|
```javascript
|
|
306
|
-
import
|
|
326
|
+
import mikel from "mikel";
|
|
307
327
|
|
|
308
328
|
const data = {
|
|
309
329
|
name: "World",
|
|
310
330
|
};
|
|
311
331
|
|
|
312
|
-
const result =
|
|
332
|
+
const result = mikel("Hello, {{name}}!", data);
|
|
313
333
|
console.log(result); // Output: "Hello, World!"
|
|
314
334
|
```
|
|
315
335
|
|
|
336
|
+
### `mikel.escape(str)`
|
|
337
|
+
|
|
338
|
+
This function converts special HTML characters `&`, `<`, `>`, `"`, and `'` to their corresponding HTML entities.
|
|
339
|
+
|
|
340
|
+
### `mikel.get(object, path)`
|
|
341
|
+
|
|
342
|
+
This function returns the value in `object` following the provided `path` string.
|
|
343
|
+
|
|
316
344
|
## License
|
|
317
345
|
|
|
318
346
|
This project is licensed under the [MIT License](LICENSE).
|
package/index.js
CHANGED
|
@@ -11,47 +11,44 @@ const escape = s => s.toString().replace(/[&<>\"']/g, m => escapedChars[m]);
|
|
|
11
11
|
|
|
12
12
|
const get = (c, p) => (p === "." ? c : p.split(".").reduce((x, k) => x?.[k], c)) ?? "";
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const defaultHelpers = {
|
|
15
15
|
"each": ({value, fn}) => {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const items = (typeof value === "object" ? Object.entries(value || {}) : []);
|
|
17
|
+
return items
|
|
18
|
+
.map((item, index) => fn(item[1], {index: index, key: item[0], value: item[1], first: index === 0, last: index === items.length - 1}))
|
|
18
19
|
.join("");
|
|
19
20
|
},
|
|
20
21
|
"if": ({value, fn, context}) => !!value ? fn(context) : "",
|
|
21
22
|
"unless": ({value, fn, context}) => !!!value ? fn(context) : "",
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const hasHelper = (n, o) => helpers.has(n) || typeof o?.helpers?.[n] === "function";
|
|
25
|
-
const getHelper = (n, o) => helpers.get(n) || o?.helpers?.[n];
|
|
23
|
+
};
|
|
26
24
|
|
|
27
|
-
const compile = (tokens, output, context,
|
|
25
|
+
const compile = (tokens, output, context, partials, helpers, vars, index = 0, section = "") => {
|
|
28
26
|
let i = index;
|
|
29
27
|
while (i < tokens.length) {
|
|
30
28
|
if (i % 2 === 0) {
|
|
31
29
|
output.push(tokens[i]);
|
|
32
30
|
}
|
|
33
31
|
else if (tokens[i].startsWith("@")) {
|
|
34
|
-
output.push(get(
|
|
32
|
+
output.push(get(vars, tokens[i].slice(1).trim() ?? "_") ?? "");
|
|
35
33
|
}
|
|
36
34
|
else if (tokens[i].startsWith("!")) {
|
|
37
35
|
output.push(get(context, tokens[i].slice(1).trim()));
|
|
38
36
|
}
|
|
39
|
-
else if (tokens[i].startsWith("#") &&
|
|
37
|
+
else if (tokens[i].startsWith("#") && typeof helpers[tokens[i].slice(1).trim().split(" ")[0]] === "function") {
|
|
40
38
|
const [t, v] = tokens[i].slice(1).trim().split(" ");
|
|
41
39
|
const j = i + 1;
|
|
42
|
-
output.push(
|
|
40
|
+
output.push(helpers[t]({
|
|
43
41
|
context: context,
|
|
44
42
|
key: v || ".",
|
|
45
|
-
value: get(context, v || "."),
|
|
46
|
-
options: opt,
|
|
43
|
+
value: (v || "").startsWith("@") ? get(vars, v.slice(1)) : get(context, v || "."),
|
|
47
44
|
fn: (blockContext = {}, blockVars = {}, blockOutput = []) => {
|
|
48
|
-
i = compile(tokens, blockOutput, blockContext,
|
|
45
|
+
i = compile(tokens, blockOutput, blockContext, partials, helpers, {...vars, ...blockVars, root: vars.root}, j, t);
|
|
49
46
|
return blockOutput.join("");
|
|
50
47
|
},
|
|
51
48
|
}));
|
|
52
49
|
// Make sure that this block has been executed
|
|
53
50
|
if (i + 1 === j) {
|
|
54
|
-
i = compile(tokens, [], {},
|
|
51
|
+
i = compile(tokens, [], {}, partials, helpers, vars, j, t);
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
else if (tokens[i].startsWith("#") || tokens[i].startsWith("^")) {
|
|
@@ -61,18 +58,18 @@ const compile = (tokens, output, context, opt, index = 0, section = "", vars = {
|
|
|
61
58
|
if (!negate && value && Array.isArray(value)) {
|
|
62
59
|
const j = i + 1;
|
|
63
60
|
(value.length > 0 ? value : [""]).forEach(item => {
|
|
64
|
-
i = compile(tokens, value.length > 0 ? output : [], item,
|
|
61
|
+
i = compile(tokens, value.length > 0 ? output : [], item, partials, helpers, vars, j, t);
|
|
65
62
|
});
|
|
66
63
|
}
|
|
67
64
|
else {
|
|
68
65
|
const includeOutput = (!negate && !!value) || (negate && !!!value);
|
|
69
|
-
i = compile(tokens, includeOutput ? output : [], context,
|
|
66
|
+
i = compile(tokens, includeOutput ? output : [], context, partials, helpers, vars, i + 1, t);
|
|
70
67
|
}
|
|
71
68
|
}
|
|
72
69
|
else if (tokens[i].startsWith(">")) {
|
|
73
70
|
const [t, v] = tokens[i].slice(1).trim().split(" ");
|
|
74
|
-
if (typeof
|
|
75
|
-
compile(
|
|
71
|
+
if (typeof partials[t] === "string") {
|
|
72
|
+
compile(partials[t].split(tags), output, v ? get(context, v) : context, partials, helpers, vars, 0, "");
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
75
|
else if (tokens[i].startsWith("/")) {
|
|
@@ -89,7 +86,17 @@ const compile = (tokens, output, context, opt, index = 0, section = "", vars = {
|
|
|
89
86
|
return i;
|
|
90
87
|
};
|
|
91
88
|
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
// @description main compiler function
|
|
90
|
+
const mikel = (str, context = {}, opt = {}, output = []) => {
|
|
91
|
+
const partials = Object.assign({}, opt.partials || {});
|
|
92
|
+
const helpers = Object.assign({}, defaultHelpers, opt.helpers || {});
|
|
93
|
+
const variables = Object.assign({}, opt.variables || {}, {root: context});
|
|
94
|
+
compile(str.split(tags), output, context, partials, helpers, variables, 0, "");
|
|
94
95
|
return output.join("");
|
|
95
96
|
};
|
|
97
|
+
|
|
98
|
+
// @description assign utilities
|
|
99
|
+
mikel.escape = escape;
|
|
100
|
+
mikel.get = get;
|
|
101
|
+
|
|
102
|
+
export default mikel;
|