mikel 0.4.0 → 0.5.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 +59 -2
- package/index.js +15 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -199,11 +199,46 @@ const data = {
|
|
|
199
199
|
console.log(m("{{#unless isAdmin}}Hello guest{{/unless}}", data)); // --> 'Hello guest'
|
|
200
200
|
```
|
|
201
201
|
|
|
202
|
-
###
|
|
202
|
+
### Custom Helpers
|
|
203
|
+
|
|
204
|
+
> Added in `v0.5.0`.
|
|
205
|
+
|
|
206
|
+
Custom helpers should be provided as an object in the `options.helpers` field, where each key represents the name of the helper and the corresponding value is a function defining the helper's behavior.
|
|
207
|
+
|
|
208
|
+
Example:
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
const template = "{{#greeting name}}{{/greeting}}";
|
|
212
|
+
const data = {
|
|
213
|
+
name: "World!",
|
|
214
|
+
};
|
|
215
|
+
const options = {
|
|
216
|
+
helpers: {
|
|
217
|
+
customHelper: ({context, value, key, options, fn}) => {
|
|
218
|
+
return `Hello, ${value}!`;
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const result = m(template, data, options);
|
|
224
|
+
console.log(result); // Output: "Hello, World!"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Custom helper functions receive a single object parameter containing the following fields:
|
|
228
|
+
|
|
229
|
+
- `context`: The current context (data) where the helper has been executed.
|
|
230
|
+
- `value`: The current value passed to the helper.
|
|
231
|
+
- `key`: The field used to extract the value from the current context.
|
|
232
|
+
- `options`: The global options object.
|
|
233
|
+
- `fn`: A function that executes the template provided in the helper block and returns a string with the evaluated template in the provided context.
|
|
234
|
+
|
|
235
|
+
The helper function must return a string, which will be injected into the result string.
|
|
236
|
+
|
|
237
|
+
### Variables
|
|
203
238
|
|
|
204
239
|
> Added in `v0.4.0`.
|
|
205
240
|
|
|
206
|
-
|
|
241
|
+
Data 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.
|
|
207
242
|
|
|
208
243
|
#### @root
|
|
209
244
|
|
|
@@ -231,6 +266,26 @@ The `@key` variable allows users to retrieve the current key of the object entry
|
|
|
231
266
|
|
|
232
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.
|
|
233
268
|
|
|
269
|
+
### Custom variables
|
|
270
|
+
|
|
271
|
+
> Added in `v0.5.0`
|
|
272
|
+
|
|
273
|
+
Mikel allows users to define custom data variables, providing enhanced flexibility and customization options for templates. These custom data variables can be accessed within the template using the `@` character.
|
|
274
|
+
|
|
275
|
+
Custom data variables should be provided in the `options.variables` field of the options object when rendering a template. Each custom data variable should be defined as a key-value pair, where the key represents the variable name and the value represents the data associated with that variable.
|
|
276
|
+
|
|
277
|
+
Example:
|
|
278
|
+
|
|
279
|
+
```javascript
|
|
280
|
+
const result = m("Hello, {{@customVariable}}!", {}, {
|
|
281
|
+
variables: {
|
|
282
|
+
customVariable: "World",
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
console.log(result); // --> 'Hello, World!'
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
In this example, the custom data variable `customVariable` is defined with the value `"World"`, and it can be accessed in the template using `@customVariable`.
|
|
234
289
|
|
|
235
290
|
## API
|
|
236
291
|
|
|
@@ -242,6 +297,8 @@ Render the given template string with the provided data object.
|
|
|
242
297
|
- `data` (object): The data object containing the values to render.
|
|
243
298
|
- `options` (object): An object containing the following optional values:
|
|
244
299
|
- `partials` (object): An object containing the available partials.
|
|
300
|
+
- `variables` (object): An object containing custom data variables.
|
|
301
|
+
- `helpers` (object): An object containing custom helpers.
|
|
245
302
|
|
|
246
303
|
Returns: A string with the rendered output.
|
|
247
304
|
|
package/index.js
CHANGED
|
@@ -7,24 +7,23 @@ const escapedChars = {
|
|
|
7
7
|
"'": "'",
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
const escape =
|
|
11
|
-
return str.toString().replace(/[&<>\"']/g, m => escapedChars[m]);
|
|
12
|
-
};
|
|
10
|
+
const escape = s => s.toString().replace(/[&<>\"']/g, m => escapedChars[m]);
|
|
13
11
|
|
|
14
|
-
const get = (
|
|
15
|
-
return (path === "." ? ctx : path.split(".").reduce((p, k) => p?.[k], ctx)) ?? "";
|
|
16
|
-
};
|
|
12
|
+
const get = (c, p) => (p === "." ? c : p.split(".").reduce((x, k) => x?.[k], c)) ?? "";
|
|
17
13
|
|
|
18
14
|
const helpers = new Map(Object.entries({
|
|
19
|
-
"
|
|
15
|
+
"each": ({value, fn}) => {
|
|
20
16
|
return (typeof value === "object" ? Object.entries(value || {}) : [])
|
|
21
|
-
.map((item, index) =>
|
|
17
|
+
.map((item, index) => fn(item[1], {index: index, key: item[0], value: item[1]}))
|
|
22
18
|
.join("");
|
|
23
19
|
},
|
|
24
|
-
"
|
|
25
|
-
"
|
|
20
|
+
"if": ({value, fn, context}) => !!value ? fn(context) : "",
|
|
21
|
+
"unless": ({value, fn, context}) => !!!value ? fn(context) : "",
|
|
26
22
|
}));
|
|
27
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];
|
|
26
|
+
|
|
28
27
|
const compile = (tokens, output, context, opt, index = 0, section = "", vars = {}) => {
|
|
29
28
|
let i = index;
|
|
30
29
|
while (i < tokens.length) {
|
|
@@ -32,17 +31,19 @@ const compile = (tokens, output, context, opt, index = 0, section = "", vars = {
|
|
|
32
31
|
output.push(tokens[i]);
|
|
33
32
|
}
|
|
34
33
|
else if (tokens[i].startsWith("@")) {
|
|
35
|
-
output.push(get(vars
|
|
34
|
+
output.push(get({...(opt?.variables), ...vars}, tokens[i].slice(1).trim() ?? "_") ?? "");
|
|
36
35
|
}
|
|
37
36
|
else if (tokens[i].startsWith("!")) {
|
|
38
37
|
output.push(get(context, tokens[i].slice(1).trim()));
|
|
39
38
|
}
|
|
40
|
-
else if (tokens[i].startsWith("#") &&
|
|
39
|
+
else if (tokens[i].startsWith("#") && hasHelper(tokens[i].slice(1).trim().split(" ")[0], opt)) {
|
|
41
40
|
const [t, v] = tokens[i].slice(1).trim().split(" ");
|
|
42
41
|
const j = i + 1;
|
|
43
|
-
output.push(
|
|
42
|
+
output.push(getHelper(t, opt)({
|
|
44
43
|
context: context,
|
|
45
|
-
|
|
44
|
+
key: v || ".",
|
|
45
|
+
value: get(context, v || "."),
|
|
46
|
+
options: opt,
|
|
46
47
|
fn: (blockContext = {}, blockVars = {}, blockOutput = []) => {
|
|
47
48
|
i = compile(tokens, blockOutput, blockContext, opt, j, t, {root: vars.root, ...blockVars});
|
|
48
49
|
return blockOutput.join("");
|