mikel 0.19.1 → 0.20.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.
Files changed (4) hide show
  1. package/README.md +104 -16
  2. package/index.d.ts +2 -0
  3. package/index.js +19 -17
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -142,11 +142,34 @@ const result = m("User: {{>user userName=name userEmail=email }}", data, {partia
142
142
 
143
143
  Please note that providing keyword arguments and a custom context to a partial is not supported. On this situation, the partial will be evaluated only with the custom context.
144
144
 
145
+ #### Expand partial arguments using the spread operator
146
+
147
+ > This feature was added in `v0.20.0`.
148
+
149
+ You can use the spread operator `...` to expand the keyword arguments of a partial. This allows you to pass an object as individual keyword arguments to the partial.
150
+
151
+ Example:
152
+
153
+ ```javascript
154
+ const data = {
155
+ user: {
156
+ name: "John Doe",
157
+ email: "john@example.com",
158
+ },
159
+ };
160
+ const partials = {
161
+ user: "{{userName}} <{{userEmail}}>",
162
+ };
163
+
164
+ const result = m("User: {{>user ...user}}", data, {partials});
165
+ console.log(result); // --> 'User: John Doe <john@example.com>'
166
+ ```
167
+
145
168
  #### Partial blocks
146
169
 
147
170
  > This feature was added in `v0.16.0`.
148
171
 
149
- You can pass a block to a partial using a greather than symbol `>>` followed by the partial name to start the partial block, and a slash followed by the partial name to end the partial block. The provided block content will be available in the `@content` variable.
172
+ You can pass a block to a partial using a double greather than symbol `>>` followed by the partial name to start the partial block, and a slash followed by the partial name to end the partial block. The provided block content will be available in the `@content` variable.
150
173
 
151
174
  Example:
152
175
 
@@ -186,24 +209,11 @@ const options = {
186
209
  },
187
210
  };
188
211
 
189
- const result = m("{{> foo}}", {}, options);
212
+ const result = m("{{>foo}}", {}, options);
190
213
  // Output: 'Hello Bob!'
191
214
  ```
192
215
 
193
- ### Inline partials
194
-
195
- > This feature was added in `v0.16.0`.
196
-
197
- Inline partials allows you to define partials directly in your template. Use the plus symbol `+` followed by the partial name to start the partial definition, and end the partial definition with a slash `/` followed by the partial name. For example, `{{<foo}}` begins a partial definition called `foo`, and `{{/foo}}` ends it.
198
-
199
- Example:
200
-
201
- ```javascript
202
- const result = m(`{{<foo}}Hello {{name}}!{{/foo}}{{>foo name="Bob"}}`, {});
203
- // Output: 'Hello Bob!'
204
- ```
205
-
206
- ### Built-in helpers
216
+ ### Helpers
207
217
 
208
218
  > Added in `v0.4.0`.
209
219
 
@@ -406,6 +416,33 @@ const result = m("{{#customEach items}}{{index}}: {{name}}, {{/customEach}}", da
406
416
  console.log(result); // --> "0: John, 1: Alice, 2: Bob,"
407
417
  ```
408
418
 
419
+ #### Expand helper arguments using the spread operator
420
+
421
+ > This feature was addedin `v0.20.0`.
422
+
423
+ You can use the spread operator `...` to expand the arguments of a helper. This allows you to pass an array of values as individual arguments to the helper, or to pass an object as keyword arguments.
424
+
425
+ Example:
426
+
427
+ ```javascript
428
+ const data = {
429
+ items: ["John", "Alice", "Bob"],
430
+ options: {
431
+ separator: ", ",
432
+ },
433
+ };
434
+ const options = {
435
+ helpers: {
436
+ join: params => {
437
+ return params.args.join(params.opt.separator);
438
+ }
439
+ },
440
+ };
441
+
442
+ const result = m("{{#join ...items ...options}}{{/join}}", data, options);
443
+ console.log(result); // --> "John, Alice, Bob"
444
+ ```
445
+
409
446
  ### Runtime Variables
410
447
 
411
448
  > Added in `v0.4.0`.
@@ -494,6 +531,57 @@ const result = m("My name is: {{=fullName user.firstName user.lastName}}", data,
494
531
  console.log(result); // --> "My name is: John Doe"
495
532
  ```
496
533
 
534
+ #### Expand function arguments using the spread operator
535
+
536
+ > This feature was addedin `v0.20.0`.
537
+
538
+ You can use the spread operator `...` to expand the arguments of a function. This allows you to pass an array of values as individual arguments to the function, or to pass an object as keyword arguments.
539
+
540
+
541
+ Example with an **array**:
542
+
543
+ ```javascript
544
+ const data = {
545
+ items: ["John", "Alice", "Bob"],
546
+ };
547
+
548
+ const options = {
549
+ functions: {
550
+ join: params => {
551
+ return params.args.join(", ");
552
+ }
553
+ },
554
+ };
555
+
556
+ const result = m("{{=join ...items}}", data, options);
557
+ console.log(result); // --> "John, Alice, Bob"
558
+ ```
559
+
560
+ Example with an **object**:
561
+
562
+ ```javascript
563
+ const data = {
564
+ user1: {
565
+ firstName: "John",
566
+ lastName: "Doe",
567
+ },
568
+ user2: {
569
+ firstName: "Alice",
570
+ lastName: "Smith",
571
+ },
572
+ };
573
+ const options = {
574
+ functions: {
575
+ fullName: params => {
576
+ return `${params.opt.firstName} ${params.opt.lastName}`;
577
+ }
578
+ },
579
+ };
580
+
581
+ const result = m("Users: {{=fullName ...user1}} and {{=fullName ...user2}}", data, options);
582
+ console.log(result); // --> "Users: John Doe and Alice Smith"
583
+ ```
584
+
497
585
 
498
586
  ## API
499
587
 
package/index.d.ts CHANGED
@@ -50,6 +50,8 @@ declare const mikel: {
50
50
  escape(str: string): string;
51
51
  get(context: any, path: string): any;
52
52
  parse(value: string, context?: any, vars?: any): any;
53
+ tokenize(value: string): string[];
54
+ untokenize(value: string[]): string;
53
55
  };
54
56
 
55
57
  export default mikel;
package/index.js CHANGED
@@ -17,13 +17,23 @@ const untokenize = (ts = [], s = "{{", e = "}}") => {
17
17
  };
18
18
 
19
19
  // @description parse string arguments
20
- const parseArgs = (argString = "", data = {}, vars = {}) => {
21
- const [t, ...args] = argString.trim().match(/(?:[^\s"]+|"[^"]*")+/g);
22
- const argv = args.filter(a => !a.includes("=")).map(a => parse(a, data, vars));
23
- const opt = Object.fromEntries(args.filter(a => a.includes("=")).map(a => {
24
- const [k, v] = a.split("=");
25
- return [k, parse(v, data, vars)];
26
- }));
20
+ const parseArgs = (str = "", data = {}, vars = {}, argv = [], opt = {}) => {
21
+ const [t, ...args] = str.trim().match(/(?:[^\s"]+|"[^"]*")+/g);
22
+ args.forEach(argStr => {
23
+ if (argStr.includes("=")) {
24
+ const [k, v] = argStr.split("=");
25
+ opt[k] = parse(v, data, vars);
26
+ }
27
+ else if (argStr.startsWith("...")) {
28
+ const value = parse(argStr.replace(/^\.{3}/, ""), data, vars);
29
+ if (!!value && typeof value === "object") {
30
+ Array.isArray(value) ? argv.push(...value) : Object.assign(opt, value);
31
+ }
32
+ }
33
+ else {
34
+ argv.push(parse(argStr, data, vars));
35
+ }
36
+ });
27
37
  return [t, argv, opt];
28
38
  };
29
39
 
@@ -101,16 +111,6 @@ const create = (template = "", options = {}) => {
101
111
  i = compile(tokens, includeOutput ? output : [], data, vars, i + 1, t);
102
112
  }
103
113
  }
104
- else if (tokens[i].startsWith("<")) {
105
- const t = tokens[i].slice(1).trim(), partialTokens = tokens.slice(i + 1);
106
- const lastIndex = partialTokens.findIndex((token, j) => {
107
- return j % 2 !== 0 && token.trim().startsWith("/") && token.trim().endsWith(t);
108
- });
109
- if (typeof ctx.partials[t] === "undefined") {
110
- ctx.partials[t] = untokenize(partialTokens.slice(0, lastIndex));
111
- }
112
- i = i + lastIndex + 1;
113
- }
114
114
  else if (tokens[i].startsWith(">")) {
115
115
  const [t, args, opt] = parseArgs(tokens[i].replace(/^>{1,2}/, ""), data, vars);
116
116
  const blockContent = []; // to store partial block content
@@ -191,5 +191,7 @@ mikel.create = create;
191
191
  mikel.escape = escape;
192
192
  mikel.get = get;
193
193
  mikel.parse = parse;
194
+ mikel.tokenize = tokenize;
195
+ mikel.untokenize = untokenize;
194
196
 
195
197
  export default mikel;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mikel",
3
3
  "description": "Micro templating library with zero dependencies",
4
- "version": "0.19.1",
4
+ "version": "0.20.0",
5
5
  "type": "module",
6
6
  "author": {
7
7
  "name": "Josemi Juanes",