mikel 0.33.1 → 0.35.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 CHANGED
@@ -25,11 +25,41 @@ Mikel supports the following syntax for rendering templates:
25
25
 
26
26
  Use double curly braces `{{ }}` to insert variables into your template. Variables will be replaced with the corresponding values from the data object.
27
27
 
28
+ ```javascript
29
+ const result = m(`Hello {{name}}!`, { name: "World" });
30
+ // Output: 'Hello World!'
31
+ ```
32
+
33
+ #### Nested values
34
+
35
+ You can access nested properties of an object using dot notation.
36
+
37
+ ```javascript
38
+ const result = m(`Hello {{user.name}}!`, {
39
+ user: { name: "John" },
40
+ });
41
+ // Output: 'Hello John!'
42
+ ```
43
+
44
+ #### Array values
45
+
46
+ You can access a specific element of an array using its index in dot notation.
47
+
48
+ ```javascript
49
+ const result = m(`Hello {{users.0.name}}!`, {
50
+ users: [
51
+ { name: "John" },
52
+ { name: "Alice" },
53
+ ],
54
+ });
55
+ // Output: 'Hello John!'
56
+ ```
57
+
28
58
  #### Fallback values
29
59
 
30
60
  > Added in `v0.14.0`.
31
61
 
32
- You can specify a value as a fallback, using the double OR `||` operator and followed by the fallback value.
62
+ You can specify a fallback value using the `||` operator. This value will be used when the variable is not defined or is empty.
33
63
 
34
64
  ```javascript
35
65
  const result = m(`Hello {{name || "World"}}!`, {});
@@ -807,19 +837,36 @@ console.log(mk("{{>hello}}", {name: "Susan"})); // --> "Hello, Susan!"
807
837
 
808
838
  It also exposes the following additional methods:
809
839
 
810
- #### `mk.use(options)`
840
+ #### `mk.use(options | function)`
811
841
 
812
842
  > Added in `v0.19.0`.
813
843
 
814
- Allows to extend the templating with custom **helpers**, **functions**, and **partials**.
815
-
844
+ Extends the instance with additional helpers, functions, partials, or hooks. Accepts either an options object or a plugin function.
845
+
846
+ When called with an **object**, it registers the provided helpers, functions, and partials directly:
847
+
816
848
  ```javascript
817
849
  mk.use({
850
+ helpers: {
851
+ uppercase: ({ fn, data }) => fn(data).toUpperCase(),
852
+ },
818
853
  partials: {
819
- foo: "bar",
854
+ foo: "Hello {{name}}!",
820
855
  },
821
856
  });
822
857
  ```
858
+
859
+ When called with a **function**, the function receives the internal context of the instance, giving full access to all registered helpers, functions, and partials. This is the recommended approach for writing reusable plugins:
860
+
861
+ ```javascript
862
+ const myPlugin = (ctx) => {
863
+ ctx.helpers.uppercase = ({ fn, data }) => {
864
+ return fn(data).toUpperCase();
865
+ };
866
+ };
867
+
868
+ mk.use(myPlugin);
869
+ ```
823
870
 
824
871
  #### `mk.addHelper(helperName, helperFn)`
825
872
 
@@ -877,6 +924,22 @@ This function converts special HTML characters `&`, `<`, `>`, `"`, and `'` to th
877
924
 
878
925
  This function returns the value in `object` following the provided `path` string.
879
926
 
927
+ ## Advanced
928
+
929
+ ### Built‑in Plugins
930
+
931
+ > Added in `v0.35.0`.
932
+
933
+ Mikel includes a small set of built‑in plugins that provide common functionality without requiring additional packages.
934
+
935
+ #### `mikel.SetStatePlugin(name, value)`
936
+
937
+ Registers a static state variable that become available inside templates through the `@variable` syntax.
938
+
939
+ ```javascript
940
+ mk.use(mikel.SetStatePlugin("version", "1.0.0"));
941
+ ```
942
+
880
943
  ## License
881
944
 
882
945
  This project is licensed under the [MIT License](LICENSE).
package/index.d.ts CHANGED
@@ -24,26 +24,39 @@ export type MikelFunction = (params: {
24
24
  state: Record<string, any>;
25
25
  }) => string | void;
26
26
 
27
+ export type MikelState = Record<string, string>;
28
+
27
29
  export type MikelOptions = {
28
30
  helpers?: Record<string, MikelHelper>;
29
31
  partials?: Record<string, string | MikelPartial>;
30
32
  functions?: Record<string, MikelFunction>;
31
33
  };
32
34
 
33
- export type MikelUseOptions = MikelOptions & {
34
- initialState?: Record<string, any>;
35
+ export type MikelPluginOptions = MikelOptions & {
36
+ initialState?: MikelState;
37
+ };
38
+
39
+ export type MikelContext = {
40
+ helpers: Record<string, MikelFunction>;
41
+ functions: Record<string, MikelFunction>;
42
+ partials: Record<string, MikelPartial>;
43
+ initialState: MikelState;
35
44
  };
36
45
 
46
+ export type MikelPlugin = (ctx: MikelContext) => void;
47
+
37
48
  export type Mikel = {
38
49
  (template: string, data?: any): string;
39
- use(options: Partial<MikelUseOptions>): void;
50
+ use(plugin: Partial<MikelPluginOptions> | MikelPlugin): void;
40
51
  addHelper(name: string, fn: MikelHelper): void;
41
52
  removeHelper(name: string): void;
42
53
  addFunction(name: string, fn: MikelFunction): void;
43
54
  removeFunction(name: string): void;
44
55
  addPartial(name: string, partial: string | MikelPartial): void;
45
56
  removePartial(name: string): void;
46
- }
57
+ };
58
+
59
+ export type MikelSetStatePlugin = (name: string, value: any) => MikelPlugin;
47
60
 
48
61
  declare const mikel: {
49
62
  (template: string, data?: any, options?: Partial<MikelOptions>): string;
@@ -53,6 +66,7 @@ declare const mikel: {
53
66
  parse(value: string, context?: any, vars?: any): any;
54
67
  tokenize(str: string): string[];
55
68
  untokenize(tokens: string[], start?: string, end?: string): string;
69
+ SetStatePlugin: MikelSetStatePlugin;
56
70
  };
57
71
 
58
72
  export default mikel;
package/index.js CHANGED
@@ -280,16 +280,22 @@ const create = (options = {}) => {
280
280
  initialState: {}, // Object.assign({}, options?.initialState || {}),
281
281
  });
282
282
  // entry method to compile the template with the provided data object
283
- const compileTemplate = (template, data = {}, output = []) => {
283
+ const compileTemplate = (template, data = {}) => {
284
+ const output = [];
284
285
  compile(ctx, tokenize(template), output, data, { ...ctx.initialState, root: data }, 0, "");
285
286
  return output.join("");
286
287
  };
287
288
  // assign api methods and return method to compile the template
288
289
  return Object.assign(compileTemplate, {
289
- use: (newOptions = {}) => {
290
- ["helpers", "functions", "partials", "initialState"].forEach(field => {
291
- Object.assign(ctx[field], newOptions?.[field] || {});
292
- });
290
+ use: (plugin) => {
291
+ if (typeof plugin === "function") {
292
+ plugin(ctx);
293
+ }
294
+ else if (typeof plugin === "object" && !!plugin) {
295
+ ["helpers", "functions", "partials", "initialState"].forEach(field => {
296
+ Object.assign(ctx[field], plugin?.[field] || {});
297
+ });
298
+ }
293
299
  },
294
300
  addHelper: (name, fn) => ctx.helpers[name] = fn,
295
301
  removeHelper: name => delete ctx.helpers[name],
@@ -305,6 +311,13 @@ const mikel = (template = "", data = {}, options = {}) => {
305
311
  return create(options)(template, data);
306
312
  };
307
313
 
314
+ // @description plugin to define a new state variable
315
+ mikel.SetStatePlugin = (name, value) => {
316
+ return (context) => {
317
+ context.initialState[name] = value;
318
+ };
319
+ };
320
+
308
321
  // @description assign utilities
309
322
  mikel.create = create;
310
323
  mikel.escape = escape;
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.33.1",
4
+ "version": "0.35.0",
5
5
  "type": "module",
6
6
  "author": {
7
7
  "name": "Josemi Juanes",
@@ -19,7 +19,8 @@
19
19
  },
20
20
  "scripts": {
21
21
  "release": "node ./scripts/release.js",
22
- "test": "node test.js && yarn test:eval && yarn test:frontmatter && yarn test:markdown",
22
+ "test": "node test.js && yarn test:cli && yarn test:eval && yarn test:frontmatter && yarn test:markdown",
23
+ "test:cli": "cd packages/mikel-cli && yarn test",
23
24
  "test:eval": "node ./packages/mikel-eval/test.js",
24
25
  "test:frontmatter": "node ./packages/mikel-frontmatter/test.js",
25
26
  "test:markdown": "node ./packages/mikel-markdown/test.js"