-
Notifications
You must be signed in to change notification settings - Fork 0
/
VentoPlugin.js
113 lines (96 loc) · 3.6 KB
/
VentoPlugin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* @file Adds support for the Vento templating language to Eleventy.
*
* @typedef VentoPluginOptions
* @prop {Function[]} [plugins=[]] An array of plugins to load into vento.
* @prop {boolean} [useEleventyFeatures=true]
* Whether Eleventy features should be enabled in templates. If true, will create tags and filters
* from Eleventy shortcodes and filters.
* @prop {boolean|string[]} [trimTags=false] Whether to automatically trim tags from output. Uses Vento's
* [autoTrim](https://vento.js.org/plugins/auto-trim/) plugin under the hood.
* @prop {boolean} [useSsrPlugin=true] Whether to load the SSR-specific syntax into Vento.
* If true, the `{{! ... }}` tag wont be removed from the output and instead kept as is. Helpful for
* hybrid rendering of pre-rendered and server-side templates.
* @prop {import('ventojs').Options} [ventoOptions] Vento engine configuration object
* that will be merged with default options.
*/
import VentoJs from 'ventojs';
import { ssr } from '#lib/ssr.js';
// Expose autotrim plugin defaults
import {
default as autoTrim,
defaultTags as ventoDefaultTrimTags,
} from 'ventojs/plugins/auto_trim.js';
export { ventoDefaultTrimTags };
/**
* @param {import('@11ty/eleventy/src/UserConfig.js').default} eleventyConfig
* @param {VentoPluginOptions} userOptions
*/
export function VentoPlugin(eleventyConfig, userOptions = {}) {
if (!('addExtension' in eleventyConfig)) {
console.log(
`[eleventy-plugin-vento] WARN Eleventy plugin compatibility: Custom templates are required for this plugin, please use Eleventy v1.0 or newer.`
);
}
/** @type {VentoPluginOptions} */
const options = {
// Define defaults
trimTags: false,
plugins: [],
useSsrPlugin: true,
useEleventyFeatures: true,
ventoOptions: {
includes: eleventyConfig.directories.includes,
autoescape: false,
},
// Merge in user-provided options
...userOptions,
};
// Init vento
const ventoEnv = VentoJs(options.ventoOptions);
// Load user-defined plugins into vento
for (const plugin of options.plugins) ventoEnv.use(plugin);
// Load ssr plugin
ventoEnv.use(ssr);
// Add autotrim plugin if enabled
if (userOptions.trimTags === true) ventoEnv.use(autoTrim());
else if (userOptions.trimTags) ventoEnv.use(autoTrim({ tags: userOptions.trimTags }));
eleventyConfig.on('eleventy.before', () => ventoEnv.cache.clear());
// Add vto as a template format
eleventyConfig.addTemplateFormats('vto');
// Add vto extension handling
eleventyConfig.addExtension('vto', {
outputFileExtension: 'html',
async compile(inputContent, inputPath) {
return async function (data) {
if (options.useEleventyFeatures) {
// Add context to filters
for (const name in eleventyConfig.getFilters()) {
// Retrieve filter
const filter = eleventyConfig.getFilter(name);
// Wrap filter with a function that augments the filter function
// with the data from Vento to extract `page` and `eleventy`
// values, then returns a call to that filter with the original arguments
ventoEnv.filters[name] = function (...filterArguments) {
const filterWithContext = eleventyConfig.augmentFunctionContext(filter, {
source: this.data,
});
return filterWithContext(...filterArguments);
};
}
}
const result = await ventoEnv.runString(inputContent, data, inputPath);
return result.content;
};
},
compileOptions: {
permalink(linkContents) {
if (typeof linkContents !== 'string') return linkContents;
return async (data) => {
const result = await ventoEnv.runString(linkContents, data);
return result.content;
};
},
},
});
}