eleventy-plugin-vento 3.1.0 → 3.2.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 +18 -0
- package/package.json +3 -6
- package/readme.md +4 -3
- package/src/engine.js +94 -63
- package/src/index.js +23 -24
- package/src/modules/create-vento-tag.js +2 -2
- package/src/modules/utils.js +16 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# eleventy-plugin-vento
|
|
2
2
|
|
|
3
|
+
## 3.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f9388e1: Further refine caching between Eleventy and Vento: commit ec02a765 deferred **all** caching to Vento and turned off Eleventy's cache (released in 3.1.0). This release allows Vento to cache only the templates that Eleventy can't cache (permalinks, includes, etc.), and Eleventy caches everything else.
|
|
8
|
+
|
|
9
|
+
A performance oversight has also been resolved by this change. Now, template functions are pre-compiled and saved by Eleventy, only running the template on render without having to go through a re-compile or get a template from the cache.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 693e1a2: Refactored the following features internally:
|
|
14
|
+
|
|
15
|
+
- Reverts 2c3548c1 for modularity: The compatibility check has moved back to `modules/utils.js`
|
|
16
|
+
- Revises caching further: Instead of deferring to Vento for everything, permalink templates and templates loaded by Vento (like includes) are cached by Vento. Everything else is cached by Eleventy.
|
|
17
|
+
- Rename some internal variables to help with readability (`_11ty.ctx => _11Ctx`)
|
|
18
|
+
- `DEBUG` key `Eleventy:Vento:Template` renamed to `Eleventy:Vento:Render`
|
|
19
|
+
- Declare engine functions separately and return as an object after everything has been declared.
|
|
20
|
+
|
|
3
21
|
## 3.1.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eleventy-plugin-vento",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Adds support for the Vento templating language to Eleventy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=16"
|
|
8
8
|
},
|
|
9
|
-
"imports": {
|
|
10
|
-
"#11ty-test": "./tests/_utils/eleventy-test.js"
|
|
11
|
-
},
|
|
12
9
|
"exports": {
|
|
13
10
|
".": {
|
|
14
11
|
"import": "./src/index.js"
|
|
@@ -47,7 +44,7 @@
|
|
|
47
44
|
"eslint-config-prettier": "9.1.0",
|
|
48
45
|
"eslint-plugin-unicorn": "56.0.0",
|
|
49
46
|
"globals": "15.11.0",
|
|
50
|
-
"vitest": "2.1.
|
|
47
|
+
"vitest": "2.1.4"
|
|
51
48
|
},
|
|
52
49
|
"prettier": {
|
|
53
50
|
"bracketSameLine": true,
|
|
@@ -56,7 +53,7 @@
|
|
|
56
53
|
"trailingComma": "es5"
|
|
57
54
|
},
|
|
58
55
|
"scripts": {
|
|
59
|
-
"test": "vitest
|
|
56
|
+
"test": "vitest",
|
|
60
57
|
"lint": "eslint '**/*.js'",
|
|
61
58
|
"ci:version": "changeset version && pnpm install --no-frozen-lockfile",
|
|
62
59
|
"ci:publish": "changeset publish",
|
package/readme.md
CHANGED
|
@@ -17,6 +17,7 @@ An [Eleventy](https://11ty.dev/) plugin that adds support for [Vento](https://ve
|
|
|
17
17
|
[Vento Plugins](#vento-plugins)<br>
|
|
18
18
|
[Auto-Trimming Tags](#auto-trimming-tags)<br>
|
|
19
19
|
[Ignoring Tags](#ignoring-tags)<br>
|
|
20
|
+
[Debugging](#debugging)<br>
|
|
20
21
|
|
|
21
22
|
## Installing
|
|
22
23
|
|
|
@@ -28,7 +29,7 @@ npm install eleventy-plugin-vento
|
|
|
28
29
|
|
|
29
30
|
This plugin is ESM only and cannot be required from CommonJS.
|
|
30
31
|
|
|
31
|
-
If you're using CommonJS and loading it asynchronously (ie `await import`), you will need at **minimum** Eleventy v3.0.0-alpha.15 which provides internal methods this plugin uses to
|
|
32
|
+
If you're using CommonJS and loading it asynchronously (ie `await import`), you will need at **minimum** Eleventy v3.0.0-alpha.15 which provides internal methods this plugin uses to retrieve Eleventy features from the config API.
|
|
32
33
|
|
|
33
34
|
In your Eleventy config:
|
|
34
35
|
|
|
@@ -101,7 +102,7 @@ Eleventy: See [Filters](https://www.11ty.dev/docs/filters/)
|
|
|
101
102
|
> [!NOTE]
|
|
102
103
|
> Remember, Vento can print any return value from a Javascript expression, as well as [run arbitrary JavaScript](https://vento.js.org/syntax/javascript/) in templates through its `{{> ...}}` operator. In these cases, shortcodes may not be needed depending on your usage.
|
|
103
104
|
|
|
104
|
-
Single and Paired Shortcodes added via Eleventy's `.addShortcode()`,
|
|
105
|
+
Single and Paired Shortcodes added via Eleventy's `.addShortcode()`, `.addAsyncShortcode()`, `.addPairedShortcode()` or `.addAsyncPairedShortcode()` will be automatically loaded into Vento.
|
|
105
106
|
|
|
106
107
|
When using shortcodes in your templates, write them like any other Vento tag:
|
|
107
108
|
|
|
@@ -272,7 +273,7 @@ Like Eleventy, this plugin uses the [`debug`](https://www.npmjs.com/package/debu
|
|
|
272
273
|
|
|
273
274
|
- `Eleventy:Vento:Setup` - Logs initial setup of the plugin, loading features, pre-page compile setup steps (like changing `page` and `eleventy` objects)
|
|
274
275
|
- `Eleventy:Vento:Cache` - Logs updates to Vento's own internal cache, which is used in tandem with Eleventy's cache.
|
|
275
|
-
- `Eleventy:Vento:
|
|
276
|
+
- `Eleventy:Vento:Render` - Logs when templates are rendered
|
|
276
277
|
|
|
277
278
|
Because it is a child of the `Eleventy:` namespace, the following command will include output from this plugin as well:
|
|
278
279
|
|
package/src/engine.js
CHANGED
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
* a simple API for Eleventy to interface with.
|
|
4
4
|
*
|
|
5
5
|
* @typedef {{eleventy?: Record<string, unknown>, page?: Record<string, unknown>}} EleventyContext
|
|
6
|
-
* @typedef {
|
|
6
|
+
* @typedef {EleventyContext & Record<string, unknown>} EleventyData
|
|
7
7
|
* @typedef {(...args: unknown[]) => unknown} EleventyFunction
|
|
8
|
+
* @typedef {Record<string, EleventyFunction>} EleventyFunctionSet
|
|
8
9
|
* @typedef {import('ventojs/src/environment.js').Environment} VentoEnvironment
|
|
9
10
|
* @typedef {VentoEnvironment & {
|
|
10
|
-
*
|
|
11
|
+
* utils: {
|
|
12
|
+
* _11tyFns: { shortcodes: EleventyFunctionSet, pairedShortcodes: EleventyFunctionSet }
|
|
13
|
+
* _11tyCtx: EleventyContext
|
|
14
|
+
* }
|
|
11
15
|
* }} EleventyVentoEnvironment
|
|
12
16
|
*/
|
|
13
17
|
|
|
@@ -16,80 +20,107 @@ import ventojs from 'ventojs';
|
|
|
16
20
|
|
|
17
21
|
// Internal modules
|
|
18
22
|
import { createVentoTag } from './modules/create-vento-tag.js';
|
|
19
|
-
import {
|
|
23
|
+
import { CONTEXT_DATA_KEYS, DEBUG } from './modules/utils.js';
|
|
20
24
|
|
|
21
25
|
/** @param {import('ventojs').Options} options */
|
|
22
26
|
export function createVentoEngine(options) {
|
|
23
27
|
/** @type {EleventyVentoEnvironment} */
|
|
24
28
|
const env = ventojs(options);
|
|
25
|
-
env.utils.
|
|
29
|
+
env.utils._11tyFns = { shortcodes: {}, pairedShortcodes: {} };
|
|
30
|
+
env.utils._11tyCtx = {};
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
/** @param {EleventyData} newContext */
|
|
33
|
+
function setContext(newContext) {
|
|
34
|
+
if (env.utils._11tyCtx?.page?.inputPath === newContext?.page?.inputPath) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
env.use(plugin);
|
|
34
|
-
}
|
|
35
|
-
},
|
|
38
|
+
for (const K of CONTEXT_DATA_KEYS) {
|
|
39
|
+
env.utils._11tyCtx[K] = newContext[K];
|
|
40
|
+
}
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// Loop through allowed keys and load those into the context
|
|
40
|
-
for (const K of CONTEXT_DATA_KEYS) {
|
|
41
|
-
env.utils._11ty.ctx[K] = newContext[K];
|
|
42
|
-
}
|
|
43
|
-
},
|
|
42
|
+
DEBUG.setup('Reload context, new context is: %o', env.utils._11tyCtx);
|
|
43
|
+
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
/** @param {import('ventojs/src/environment.js').Plugin[]} plugins */
|
|
46
|
+
function loadPlugins(plugins) {
|
|
47
|
+
for (const plugin of plugins) {
|
|
48
|
+
env.use(plugin);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
52
|
+
/** @param {Record<string, EleventyFunction>} filters */
|
|
53
|
+
function loadFilters(filters) {
|
|
54
|
+
for (const [name, fn] of Object.entries(filters)) {
|
|
55
|
+
env.filters[name] = fn.bind(env.utils._11tyCtx);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
59
|
+
/** @param {Record<string, EleventyFunction>} shortcodes */
|
|
60
|
+
function loadShortcodes(shortcodes) {
|
|
61
|
+
for (const [name, fn] of Object.entries(shortcodes)) {
|
|
62
|
+
env.utils._11tyFns.shortcodes[name] = fn;
|
|
63
|
+
env.tags.push(createVentoTag({ name, group: 'shortcodes' }));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** @param {Record<string, EleventyFunction>} pairedShortcodes */
|
|
68
|
+
function loadPairedShortcodes(pairedShortcodes) {
|
|
69
|
+
for (const [name, fn] of Object.entries(pairedShortcodes)) {
|
|
70
|
+
env.utils._11tyFns.pairedShortcodes[name] = fn;
|
|
71
|
+
env.tags.push(createVentoTag({ name, group: 'pairedShortcodes' }));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {string} source
|
|
77
|
+
* @param {string} file
|
|
78
|
+
* @param {boolean} [useVentoCache=true]
|
|
79
|
+
*/
|
|
80
|
+
function getTemplateFunction(source, file, useVentoCache = true) {
|
|
81
|
+
// Attempt to retrieve template function from cache
|
|
82
|
+
let template = env.cache.get(file);
|
|
83
|
+
|
|
84
|
+
if (template?.source === source) {
|
|
85
|
+
DEBUG.cache('Cache HIT for `%s`, used precompiled template', file);
|
|
86
|
+
} else {
|
|
87
|
+
template = env.compile(source, file);
|
|
88
|
+
|
|
89
|
+
DEBUG.cache(
|
|
90
|
+
`Cache MISS for \`%s\`, compiled new template:\nUse Vento cache: %o\n\n${template}`,
|
|
91
|
+
file,
|
|
92
|
+
useVentoCache
|
|
93
|
+
);
|
|
94
|
+
if (useVentoCache) {
|
|
95
|
+
env.cache.set(file, template);
|
|
86
96
|
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return template;
|
|
100
|
+
}
|
|
87
101
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
102
|
+
/**
|
|
103
|
+
* @param {import('ventojs/src/environment.js').Template} template
|
|
104
|
+
* @param {EleventyData} data
|
|
105
|
+
* @param {string} from
|
|
106
|
+
*/
|
|
107
|
+
async function render(template, data, from) {
|
|
108
|
+
// Load new context
|
|
109
|
+
setContext(data);
|
|
91
110
|
|
|
92
|
-
|
|
93
|
-
|
|
111
|
+
// Render template
|
|
112
|
+
DEBUG.render('Rendering `%s`', from);
|
|
113
|
+
const { content } = await template(data);
|
|
114
|
+
return content;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
cache: env.cache,
|
|
119
|
+
loadPlugins,
|
|
120
|
+
loadFilters,
|
|
121
|
+
loadShortcodes,
|
|
122
|
+
loadPairedShortcodes,
|
|
123
|
+
getTemplateFunction,
|
|
124
|
+
render,
|
|
94
125
|
};
|
|
95
126
|
}
|
package/src/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import autotrimPlugin, { defaultTags as autotrimDefaultTags } from 'ventojs/plug
|
|
|
29
29
|
// Local modules
|
|
30
30
|
import { createVentoEngine } from './engine.js';
|
|
31
31
|
import { ignoreTagPlugin } from './modules/ignore-tag.js';
|
|
32
|
-
import { DEBUG,
|
|
32
|
+
import { DEBUG, runCompatibilityCheck } from './modules/utils.js';
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* @param {import('@11ty/eleventy').UserConfig} eleventyConfig
|
|
@@ -37,18 +37,7 @@ import { DEBUG, PERMALINK_PREFIX, REQUIRED_API_METHODS } from './modules/utils.j
|
|
|
37
37
|
*/
|
|
38
38
|
export function VentoPlugin(eleventyConfig, userOptions) {
|
|
39
39
|
DEBUG.setup('Initializing eleventy-plugin-vento');
|
|
40
|
-
|
|
41
|
-
for (const [method, version] of REQUIRED_API_METHODS) {
|
|
42
|
-
if (!eleventyConfig?.[method]) {
|
|
43
|
-
console.error(
|
|
44
|
-
'[eleventy-plugin-vento] Plugin compatibility error:',
|
|
45
|
-
`\`${method}\``,
|
|
46
|
-
'not found. Please use Eleventy',
|
|
47
|
-
version,
|
|
48
|
-
'or later.'
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
40
|
+
runCompatibilityCheck(eleventyConfig);
|
|
52
41
|
|
|
53
42
|
/** @type {VentoPluginOptions} */
|
|
54
43
|
const options = {
|
|
@@ -153,26 +142,36 @@ export function VentoPlugin(eleventyConfig, userOptions) {
|
|
|
153
142
|
outputFileExtension: 'html',
|
|
154
143
|
read: true,
|
|
155
144
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
145
|
+
compile(inputContent, inputPath) {
|
|
146
|
+
// Normalize input path
|
|
147
|
+
inputPath = path.normalize(inputPath);
|
|
148
|
+
|
|
149
|
+
// Retrieve the template function
|
|
150
|
+
const template = engine.getTemplateFunction(inputContent, inputPath, false);
|
|
151
|
+
|
|
152
|
+
// Return a render function
|
|
153
|
+
return async (data) => await engine.render(template, data, inputPath);
|
|
160
154
|
},
|
|
161
155
|
|
|
162
156
|
compileOptions: {
|
|
163
|
-
// Defer all caching to Vento
|
|
164
|
-
cache: false,
|
|
165
157
|
// Custom permalink compilation
|
|
166
|
-
permalink(
|
|
158
|
+
permalink(permalinkContent, inputPath) {
|
|
167
159
|
// Short circuit if input isn't a string and doesn't look like a vento template
|
|
168
|
-
if (typeof
|
|
169
|
-
|
|
170
|
-
|
|
160
|
+
if (typeof permalinkContent === 'string' && /\{\{\s+.+\s+\}\}/.test(permalinkContent)) {
|
|
161
|
+
// Normalize input path
|
|
162
|
+
inputPath = 'Permalink::' + path.normalize(inputPath);
|
|
163
|
+
|
|
164
|
+
// Retrieve the template function
|
|
165
|
+
const template = engine.getTemplateFunction(permalinkContent, inputPath);
|
|
166
|
+
|
|
167
|
+
// Return a render function
|
|
168
|
+
return async (data) => await engine.render(template, data, inputPath);
|
|
171
169
|
}
|
|
172
170
|
|
|
173
|
-
return
|
|
171
|
+
return permalinkContent;
|
|
174
172
|
},
|
|
175
173
|
},
|
|
176
174
|
});
|
|
175
|
+
|
|
177
176
|
DEBUG.setup('eleventy-plugin-vento initialized');
|
|
178
177
|
}
|
|
@@ -12,8 +12,8 @@ export function createVentoTag(options) {
|
|
|
12
12
|
if (!code.startsWith(options.name)) return;
|
|
13
13
|
|
|
14
14
|
// Declare helper variables for repeated strings in template
|
|
15
|
-
const fn = `__env.utils.
|
|
16
|
-
const ctx = '__env.utils.
|
|
15
|
+
const fn = `__env.utils._11tyFns.${options.group}.${options.name}`;
|
|
16
|
+
const ctx = '__env.utils._11tyCtx';
|
|
17
17
|
const args = [code.replace(options.name, '').trim()];
|
|
18
18
|
|
|
19
19
|
const varname = output.startsWith('__shortcode_content')
|
package/src/modules/utils.js
CHANGED
|
@@ -4,7 +4,7 @@ const debugBaseNamespace = 'Eleventy:Vento';
|
|
|
4
4
|
export const DEBUG = {
|
|
5
5
|
setup: createDebugger(`${debugBaseNamespace}:Setup`),
|
|
6
6
|
cache: createDebugger(`${debugBaseNamespace}:Cache`),
|
|
7
|
-
|
|
7
|
+
render: createDebugger(`${debugBaseNamespace}:Render`),
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
// Project-wide constants
|
|
@@ -17,4 +17,18 @@ export const REQUIRED_API_METHODS = [
|
|
|
17
17
|
|
|
18
18
|
export const CONTEXT_DATA_KEYS = ['page', 'eleventy'];
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// Helper functions
|
|
21
|
+
export function runCompatibilityCheck(config) {
|
|
22
|
+
DEBUG.setup('Run compatibility check');
|
|
23
|
+
for (const [method, version] of REQUIRED_API_METHODS) {
|
|
24
|
+
if (!config?.[method]) {
|
|
25
|
+
console.error(
|
|
26
|
+
'[eleventy-plugin-vento] Plugin compatibility error:',
|
|
27
|
+
`\`${method}\``,
|
|
28
|
+
'not found. Please use Eleventy',
|
|
29
|
+
version,
|
|
30
|
+
'or later.'
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|