eleventy-plugin-vento 4.0.0 → 4.1.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/CHANGELOG.md +23 -0
- package/dist/index.js +49 -52
- package/package.json +12 -10
- package/readme.md +38 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# eleventy-plugin-vento
|
|
2
2
|
|
|
3
|
+
## 4.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- eb33d79: Expose Vento's `FilterThis` on Eleventy-declared filters. (fixes #72)
|
|
8
|
+
|
|
9
|
+
> [!IMPORTANT]
|
|
10
|
+
> Using this feature incurs the same performance regression that [`eleventyComputed` template strings](https://www.11ty.dev/docs/data-computed/#using-a-template-string) do. Caching can assist with this, see [README](https://github.com/noelforte/eleventy-plugin-vento/blob/main/readme.md) for more information.
|
|
11
|
+
|
|
12
|
+
Vento binds its own `this` object when executing filter functions. The `this` object contains 2 keys, `this.env` and `this.data`, for getting access to both the Vento environment and the template data respectively.
|
|
13
|
+
|
|
14
|
+
In addition to Vento's object, `this.page` and `this.eleventy` are also cloned to the top level from `this.data` to maintain feature-parity with Eleventy.
|
|
15
|
+
|
|
16
|
+
With this change, you can now create filters that leverage the Vento environment. See [README](https://github.com/noelforte/eleventy-plugin-vento/blob/main/readme.md) for more info.
|
|
17
|
+
|
|
18
|
+
- eb33d79: Update vento to 1.12.12
|
|
19
|
+
|
|
20
|
+
## 4.0.1
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- hotfix - include `types` field in package.json to declare bundled types
|
|
25
|
+
|
|
3
26
|
## 4.0.0
|
|
4
27
|
|
|
5
28
|
### Major Changes
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import autotrimPlugin, { defaultTags as autotrimDefaultTags } from "ventojs/plugins/auto_trim.js";
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/engine.ts
|
|
6
6
|
import { default as ventojs } from "ventojs";
|
|
7
7
|
|
|
8
8
|
// src/create-vento-tag.ts
|
|
@@ -10,8 +10,12 @@ function createVentoTag(spec) {
|
|
|
10
10
|
const IS_PAIRED = spec.group === "pairedShortcodes";
|
|
11
11
|
const tag = (env, code, output, tokens) => {
|
|
12
12
|
if (!code.startsWith(spec.name)) return;
|
|
13
|
-
const
|
|
14
|
-
const
|
|
13
|
+
const { dataVarname } = env.options;
|
|
14
|
+
const thisArg = `{
|
|
15
|
+
page: ${dataVarname}.page,
|
|
16
|
+
eleventy: ${dataVarname}.eleventy
|
|
17
|
+
}`;
|
|
18
|
+
const fn = `__env.utils.eleventyFunctions.${spec.group}.${spec.name}`;
|
|
15
19
|
const args = [code.replace(spec.name, "").trim()];
|
|
16
20
|
const varname = output.startsWith("__shortcode_content") ? `${output}_precomp` : "__shortcode_content";
|
|
17
21
|
const compiled = [];
|
|
@@ -27,7 +31,7 @@ function createVentoTag(spec) {
|
|
|
27
31
|
}
|
|
28
32
|
tokens.shift();
|
|
29
33
|
}
|
|
30
|
-
args.unshift(
|
|
34
|
+
args.unshift(thisArg);
|
|
31
35
|
compiled.push(
|
|
32
36
|
"{",
|
|
33
37
|
`const __shortcode_result = await ${fn}.call(${args.filter(Boolean).join(", ")});`,
|
|
@@ -49,7 +53,7 @@ function createVentoTag(spec) {
|
|
|
49
53
|
import createDebugger from "debug";
|
|
50
54
|
var debugBaseNamespace = "Eleventy:Vento";
|
|
51
55
|
var DEBUG = {
|
|
52
|
-
|
|
56
|
+
main: createDebugger(debugBaseNamespace),
|
|
53
57
|
cache: createDebugger(`${debugBaseNamespace}:Cache`),
|
|
54
58
|
render: createDebugger(`${debugBaseNamespace}:Render`)
|
|
55
59
|
};
|
|
@@ -59,9 +63,8 @@ var REQUIRED_API_METHODS = [
|
|
|
59
63
|
["getFilters", "v3.0.0-alpha.15"],
|
|
60
64
|
["addExtension", "v1.0.0"]
|
|
61
65
|
];
|
|
62
|
-
var CONTEXT_DATA_KEYS = ["page", "eleventy"];
|
|
63
66
|
function runCompatibilityCheck(config) {
|
|
64
|
-
DEBUG.
|
|
67
|
+
DEBUG.main("Run compatibility check");
|
|
65
68
|
for (const [method, version] of REQUIRED_API_METHODS) {
|
|
66
69
|
if (!(method in config)) {
|
|
67
70
|
console.error(
|
|
@@ -75,20 +78,11 @@ function runCompatibilityCheck(config) {
|
|
|
75
78
|
}
|
|
76
79
|
}
|
|
77
80
|
|
|
78
|
-
// src/
|
|
79
|
-
function
|
|
81
|
+
// src/engine.ts
|
|
82
|
+
function createVentoEngine(options) {
|
|
80
83
|
const env = ventojs(options);
|
|
81
|
-
env.utils.
|
|
84
|
+
env.utils.eleventyFunctions = { shortcodes: {}, pairedShortcodes: {} };
|
|
82
85
|
env.utils._11tyCtx = {};
|
|
83
|
-
function setContext(newContext) {
|
|
84
|
-
if (env.utils._11tyCtx?.page?.inputPath === newContext?.page?.inputPath) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
for (const K of CONTEXT_DATA_KEYS) {
|
|
88
|
-
env.utils._11tyCtx[K] = newContext[K];
|
|
89
|
-
}
|
|
90
|
-
DEBUG.setup("Reload context, new context is: %o", env.utils._11tyCtx);
|
|
91
|
-
}
|
|
92
86
|
function loadPlugins(plugins) {
|
|
93
87
|
for (const plugin of plugins) {
|
|
94
88
|
env.use(plugin);
|
|
@@ -96,18 +90,21 @@ function createVentoInterface(options) {
|
|
|
96
90
|
}
|
|
97
91
|
function loadFilters(filters) {
|
|
98
92
|
for (const [name, fn] of Object.entries(filters)) {
|
|
99
|
-
env.filters[name] =
|
|
93
|
+
env.filters[name] = async function(...args) {
|
|
94
|
+
Object.assign(this, { page: this.data.page, eleventy: this.data.eleventy });
|
|
95
|
+
return await fn.apply(this, args);
|
|
96
|
+
};
|
|
100
97
|
}
|
|
101
98
|
}
|
|
102
99
|
function loadShortcodes(shortcodes) {
|
|
103
100
|
for (const [name, fn] of Object.entries(shortcodes)) {
|
|
104
|
-
env.utils.
|
|
101
|
+
env.utils.eleventyFunctions.shortcodes[name] = fn;
|
|
105
102
|
env.tags.push(createVentoTag({ name, group: "shortcodes" }));
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
function loadPairedShortcodes(pairedShortcodes) {
|
|
109
106
|
for (const [name, fn] of Object.entries(pairedShortcodes)) {
|
|
110
|
-
env.utils.
|
|
107
|
+
env.utils.eleventyFunctions.pairedShortcodes[name] = fn;
|
|
111
108
|
env.tags.push(createVentoTag({ name, group: "pairedShortcodes" }));
|
|
112
109
|
}
|
|
113
110
|
}
|
|
@@ -131,26 +128,24 @@ ${template}`,
|
|
|
131
128
|
}
|
|
132
129
|
return template;
|
|
133
130
|
}
|
|
134
|
-
async function render(template, data, from) {
|
|
135
|
-
setContext(data);
|
|
136
|
-
DEBUG.render("Rendering `%s`", from);
|
|
137
|
-
const { content } = await template(data);
|
|
138
|
-
return content;
|
|
139
|
-
}
|
|
140
131
|
return {
|
|
141
132
|
cache: env.cache,
|
|
142
133
|
loadPlugins,
|
|
143
134
|
loadFilters,
|
|
144
135
|
loadShortcodes,
|
|
145
136
|
loadPairedShortcodes,
|
|
146
|
-
getTemplateFunction
|
|
147
|
-
render
|
|
137
|
+
getTemplateFunction
|
|
148
138
|
};
|
|
149
139
|
}
|
|
140
|
+
async function renderVentoTemplate(template, data, from) {
|
|
141
|
+
DEBUG.render("Rendering `%s`", from);
|
|
142
|
+
const { content } = await template(data);
|
|
143
|
+
return content;
|
|
144
|
+
}
|
|
150
145
|
|
|
151
146
|
// src/index.ts
|
|
152
147
|
function VentoPlugin(eleventyConfig, userOptions) {
|
|
153
|
-
DEBUG.
|
|
148
|
+
DEBUG.main("Initializing eleventy-plugin-vento");
|
|
154
149
|
runCompatibilityCheck(eleventyConfig);
|
|
155
150
|
const options = {
|
|
156
151
|
// Define defaults
|
|
@@ -165,13 +160,13 @@ function VentoPlugin(eleventyConfig, userOptions) {
|
|
|
165
160
|
// Merge in user-provided options
|
|
166
161
|
...userOptions
|
|
167
162
|
};
|
|
168
|
-
DEBUG.
|
|
163
|
+
DEBUG.main("Merged default and user config: %O", options);
|
|
169
164
|
const filters = eleventyConfig.getFilters();
|
|
170
|
-
DEBUG.
|
|
165
|
+
DEBUG.main("Reading filters from Eleventy: %o", filters);
|
|
171
166
|
const shortcodes = eleventyConfig.getShortcodes();
|
|
172
|
-
DEBUG.
|
|
167
|
+
DEBUG.main("Reading shortcodes from Eleventy: %o", shortcodes);
|
|
173
168
|
const pairedShortcodes = eleventyConfig.getPairedShortcodes();
|
|
174
|
-
DEBUG.
|
|
169
|
+
DEBUG.main("Reading paired shortcodes from Eleventy: %o", pairedShortcodes);
|
|
175
170
|
if (options.autotrim) {
|
|
176
171
|
const defaults = ["@vento", "@11ty"];
|
|
177
172
|
const tagSet = new Set(options.autotrim === true ? defaults : options.autotrim);
|
|
@@ -187,26 +182,26 @@ function VentoPlugin(eleventyConfig, userOptions) {
|
|
|
187
182
|
tagSet.add(name);
|
|
188
183
|
}
|
|
189
184
|
}
|
|
190
|
-
DEBUG.
|
|
185
|
+
DEBUG.main("Enabled autotrim for tags: %o", tagSet);
|
|
191
186
|
options.plugins.push(autotrimPlugin({ tags: [...tagSet] }));
|
|
192
187
|
}
|
|
193
|
-
DEBUG.
|
|
194
|
-
const engine =
|
|
195
|
-
DEBUG.
|
|
188
|
+
DEBUG.main("Initializing Vento environment");
|
|
189
|
+
const engine = createVentoEngine(options.ventoOptions);
|
|
190
|
+
DEBUG.main("Loading plugins: %o", options.plugins);
|
|
196
191
|
engine.loadPlugins(options.plugins);
|
|
197
192
|
if (options.filters) {
|
|
198
|
-
DEBUG.
|
|
193
|
+
DEBUG.main("Loading filters: %o", filters);
|
|
199
194
|
engine.loadFilters(filters);
|
|
200
195
|
}
|
|
201
196
|
if (options.shortcodes) {
|
|
202
|
-
DEBUG.
|
|
197
|
+
DEBUG.main("Loading shortcodes: %o", shortcodes);
|
|
203
198
|
engine.loadShortcodes(shortcodes);
|
|
204
199
|
}
|
|
205
200
|
if (options.pairedShortcodes) {
|
|
206
|
-
DEBUG.
|
|
201
|
+
DEBUG.main("Loading paired shortcodes: %o", pairedShortcodes);
|
|
207
202
|
engine.loadPairedShortcodes(pairedShortcodes);
|
|
208
203
|
}
|
|
209
|
-
DEBUG.
|
|
204
|
+
DEBUG.main("Registering Vento cache handler on eleventy.beforeWatch event");
|
|
210
205
|
eleventyConfig.on("eleventy.beforeWatch", async (updatedFiles) => {
|
|
211
206
|
for (let file of updatedFiles) {
|
|
212
207
|
file = path.normalize(file);
|
|
@@ -214,30 +209,32 @@ function VentoPlugin(eleventyConfig, userOptions) {
|
|
|
214
209
|
engine.cache.delete(file);
|
|
215
210
|
}
|
|
216
211
|
});
|
|
217
|
-
DEBUG.
|
|
212
|
+
DEBUG.main("Registering .vto as a template format");
|
|
218
213
|
eleventyConfig.addTemplateFormats("vto");
|
|
219
|
-
DEBUG.
|
|
214
|
+
DEBUG.main("Registering .vto extension with eleventy");
|
|
220
215
|
eleventyConfig.addExtension("vto", {
|
|
221
216
|
outputFileExtension: "html",
|
|
222
217
|
read: true,
|
|
223
218
|
compile(inputContent, inputPath) {
|
|
224
219
|
inputPath = path.normalize(inputPath);
|
|
220
|
+
DEBUG.main("Getting template function for `%s`", inputPath);
|
|
225
221
|
const template = engine.getTemplateFunction(inputContent, inputPath, false);
|
|
226
|
-
return async (data) => await
|
|
222
|
+
return async (data) => await renderVentoTemplate(template, data, inputPath);
|
|
227
223
|
},
|
|
228
224
|
compileOptions: {
|
|
229
225
|
// Custom permalink compilation
|
|
230
226
|
permalink(permalinkContent, inputPath) {
|
|
231
|
-
if (typeof permalinkContent
|
|
232
|
-
|
|
233
|
-
const template = engine.getTemplateFunction(permalinkContent, inputPath);
|
|
234
|
-
return async (data) => await engine.render(template, data, inputPath);
|
|
227
|
+
if (typeof permalinkContent !== "string" || !/\{\{\s+.+\s+\}\}/.test(permalinkContent)) {
|
|
228
|
+
return permalinkContent;
|
|
235
229
|
}
|
|
236
|
-
|
|
230
|
+
inputPath = "Permalink::" + path.normalize(inputPath);
|
|
231
|
+
DEBUG.main("Getting template function for `%s`", inputPath);
|
|
232
|
+
const template = engine.getTemplateFunction(permalinkContent, inputPath);
|
|
233
|
+
return async (data) => await renderVentoTemplate(template, data, inputPath);
|
|
237
234
|
}
|
|
238
235
|
}
|
|
239
236
|
});
|
|
240
|
-
DEBUG.
|
|
237
|
+
DEBUG.main("eleventy-plugin-vento initialized");
|
|
241
238
|
}
|
|
242
239
|
export {
|
|
243
240
|
VentoPlugin
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eleventy-plugin-vento",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Adds support for the Vento templating language to Eleventy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=18"
|
|
8
8
|
},
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
9
10
|
"exports": {
|
|
10
11
|
".": {
|
|
11
12
|
"import": "./dist/index.js",
|
|
@@ -36,24 +37,24 @@
|
|
|
36
37
|
"license": "MIT",
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"debug": "4.3.7",
|
|
39
|
-
"ventojs": "1.12.
|
|
40
|
+
"ventojs": "1.12.12"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"11ty.ts": "0.0.5",
|
|
43
44
|
"@11ty/eleventy": "3.0.0",
|
|
44
|
-
"@changesets/cli": "2.27.
|
|
45
|
-
"@eslint/js": "9.
|
|
45
|
+
"@changesets/cli": "2.27.10",
|
|
46
|
+
"@eslint/js": "9.15.0",
|
|
46
47
|
"@types/debug": "4.1.12",
|
|
47
48
|
"@types/eslint-config-prettier": "6.11.3",
|
|
48
49
|
"@types/eslint__js": "8.42.3",
|
|
49
|
-
"@types/node": "22.
|
|
50
|
-
"eslint": "9.
|
|
50
|
+
"@types/node": "22.9.3",
|
|
51
|
+
"eslint": "9.15.0",
|
|
51
52
|
"eslint-config-prettier": "9.1.0",
|
|
52
|
-
"eslint-plugin-unicorn": "56.0.
|
|
53
|
+
"eslint-plugin-unicorn": "56.0.1",
|
|
53
54
|
"tsup": "8.3.5",
|
|
54
|
-
"typescript": "5.
|
|
55
|
-
"typescript-eslint": "8.
|
|
56
|
-
"vitest": "2.1.
|
|
55
|
+
"typescript": "5.7.2",
|
|
56
|
+
"typescript-eslint": "8.15.0",
|
|
57
|
+
"vitest": "2.1.5"
|
|
57
58
|
},
|
|
58
59
|
"prettier": {
|
|
59
60
|
"bracketSameLine": true,
|
|
@@ -67,6 +68,7 @@
|
|
|
67
68
|
"lint": "eslint '.'",
|
|
68
69
|
"ts-check": "tsc --noEmit",
|
|
69
70
|
"build": "tsup",
|
|
71
|
+
"dev": "tsup --watch ./src",
|
|
70
72
|
"ci:version": "changeset version && pnpm install --no-frozen-lockfile",
|
|
71
73
|
"ci:publish": "changeset publish",
|
|
72
74
|
"ci:generate-changesets": "node ./scripts/generate-changesets.js",
|
package/readme.md
CHANGED
|
@@ -90,6 +90,42 @@ Filters that are added via Eleventy's `.addFilter()` or `.addAsyncFilter()` meth
|
|
|
90
90
|
|
|
91
91
|
If you'd prefer to set filters yourself (via a plugin or other method) or prevent Eleventy from loading filters into Vento, set `filters: false` in the plugin options.
|
|
92
92
|
|
|
93
|
+
### Filters and `this`
|
|
94
|
+
|
|
95
|
+
This plugin merges the keys normally expected from `this` with the `FilterThis` object Vento provides to filters. The final bound `this` object for filters is as follows:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
{
|
|
99
|
+
env, // Vento environment
|
|
100
|
+
data, // all template global data
|
|
101
|
+
page, // this.page
|
|
102
|
+
eleventy, // this.eleventy
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This feature enables re-use of the Vento environment this plugin provides, within Eleventy filters. As an example use case, you could create a filter that compiles dynamic data and cache it with Vento's own cache:
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
eleventyConfig.addFilter('vento', function (content) {
|
|
110
|
+
const res = this.env.runString(content, this.data);
|
|
111
|
+
return res.content;
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Because re-compilation introduces some overhead, you may want to cache your template strings compiled via a filter. With access to `this.env` you can use Vento's own cache:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
import 'hash' from 'node:crypto'; // since Node v20.12.0
|
|
119
|
+
|
|
120
|
+
const sha1Hash(str) => hash('sha1', str, 'hex');
|
|
121
|
+
|
|
122
|
+
eleventyConfig.addFilter('vento', function (content) {
|
|
123
|
+
const file = `dynamicString:${sha1Hash(content)}`;
|
|
124
|
+
const res = this.env.runString(content, this.data, file);
|
|
125
|
+
return res.content;
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
93
129
|
### Relevant documentation
|
|
94
130
|
|
|
95
131
|
Vento: See [Filters](https://vento.js.org/configuration/#filters) and [Pipes](https://vento.js.org/syntax/pipes/)
|
|
@@ -202,7 +238,7 @@ Vento: See [Auto Trim Plugin](https://vento.js.org/plugins/auto-trim/).
|
|
|
202
238
|
|
|
203
239
|
Like Eleventy, this plugin uses the [`debug`](https://www.npmjs.com/package/debug) package to handle verbose logging. The following `DEBUG` namespaces are implemented:
|
|
204
240
|
|
|
205
|
-
- `Eleventy:Vento
|
|
241
|
+
- `Eleventy:Vento` - Logs initial setup of the plugin, loading features, pre-page compile setup steps (like changing `page` and `eleventy` objects)
|
|
206
242
|
- `Eleventy:Vento:Cache` - Logs updates to Vento's own internal cache, which is used in tandem with Eleventy's cache.
|
|
207
243
|
- `Eleventy:Vento:Render` - Logs when templates are rendered
|
|
208
244
|
|
|
@@ -215,7 +251,7 @@ $ DEBUG='Eleventy:*' npx @11ty/eleventy
|
|
|
215
251
|
Alternatively, use a finer grained namespace to see only the output generated by `eleventy-plugin-vento`.
|
|
216
252
|
|
|
217
253
|
```sh
|
|
218
|
-
$ DEBUG='Eleventy:Vento
|
|
254
|
+
$ DEBUG='Eleventy:Vento*' npx @11ty/eleventy
|
|
219
255
|
```
|
|
220
256
|
|
|
221
257
|
```sh
|