An Eleventy plugin that adds support for Vento templates.
Installing
Usage
Plugin Options
Filters
Shortcodes (Single & Paired)
Vento Plugins
Auto-Trimming Tags
Debugging
npm install eleventy-plugin-vento
This plugin is ESM only and cannot be required from CommonJS.
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.
In your Eleventy config:
import { VentoPlugin } from 'eleventy-plugin-vento';
export default function (eleventyConfig) {
eleventyConfig.addPlugin(VentoPlugin);
}
This plugin ships with default options out of the box, but you can pass an options object to your addPlugin
call to configure things further. The below example shows the configurable options as well as their defaults.
import { VentoPlugin } from 'eleventy-plugin-vento';
export default function (eleventyConfig) {
eleventyConfig.addPlugin(VentoPlugin, {
// An array of Vento plugins to use when compiling
plugins: [],
// Enable/disable Eleventy Shortcodes, Paired Shortcodes,
// and Filters in .vto templates
shortcodes: true,
pairedShortcodes: true,
filters: true,
// Define tags that should be trimmed, or set to true
// to trim the default tags (see section on Auto-trimming)
autotrim: false,
// A Vento configuration object
ventoOptions: {
includes: eleventyConfig.directories.includes,
},
});
}
View the full list of options to pass as a Vento Configuration object (as ventoOptions
).
Note
Remember, Vento can pipe any JS data type to any built-in global as the first-argument or any .prototype
method in addition to declared filters. For instance to print the eleventy
variable as JSON you could use the following snippet:
{{ eleventy |> JSON.stringify }}
In these cases, Eleventy filters may not be needed depending on your usage.
Filters that are added via Eleventy's .addFilter()
or .addAsyncFilter()
methods will be automatically loaded into Vento. Since Vento filters and Eleventy filters follow the same syntax for filters (content as first argument), the implementation is 1:1.
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.
Eleventy provides filters with scoped data via the this.page
and this.eleventy
objects (see Filters#Scoped data in Filters in Eleventy's docs for more details). Likewise, Vento provides filters with this.env
and this.data
representing the Vento environment and the current template data. This plugin merges both objects together to make this.page
(and eleventy
/env
/data
) available on all filters processed by Vento.
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 to improve performance:
import 'hash' from 'node:crypto'; // since Node v20.12.0
const sha1Hash(str) => hash('sha1', str, 'hex');
eleventyConfig.addFilter('vento', function (content) {
const file = `dynamicString:${sha1Hash(content)}`;
const res = this.env.runString(content, this.data, file);
return res.content;
});
Eleventy: See Filters
Note
Remember, Vento can print any return value from a Javascript expression, as well as run arbitrary JavaScript in templates through its {{> ...}}
operator. In these cases, shortcodes may not be needed depending on your usage.
Single and Paired Shortcodes added via Eleventy's .addShortcode()
, .addAsyncShortcode()
, .addPairedShortcode()
or .addAsyncPairedShortcode()
will be automatically loaded into Vento.
When using shortcodes in your templates, write them like any other Vento tag:
{{ myShortcode }}
To pass arguments, add a space and your arguments, comma-separated. Arguments are interpreted as JavaScript so type-safety should be considered (quote strings, use booleans if your shortcode expects them, etc.)
{{ myShortcode 'arg1', 'arg2' }}
{{ myBooleanShortcode false, false, true }}
{{ myNumberShortcode 10, 20, 0 }}
{{ myObjectShortcode { key1: 'val1', key2: 'val2' } }}
For paired shortcodes, the syntax is the same, just add a closing tag. Paired shortcodes also accept arguments and can re-process nested Vento tags (including other shortcodes).
{{ codeBlock 'css' }} <!-- takes arguments too -->
a {
color: red;
}
{{ /codeBlock }}
{{ blockQuote }}
To be or not to be, that is the question.
{{ attribute 'William Shakespeare' }} <!-- you can use vento syntax here too -->
{{ /blockQuote }}
If you'd prefer to set shortcodes yourself (via a plugin or other method) or prevent Eleventy from loading shortcodes into Vento, set shortcodes: false
and/or pairedShortcodes: false
in the plugin options.
Important
While it's straightforward to load filters via a Vento plugin that appends filters to the filters object as env.filters.[filter_name]()
, creating custom tags in Vento is more involved. It's highly advised to keep these two options enabled unless you know what you're doing.
Eleventy: See Shortcodes and the sub-section on Paired Shortcodes.
Note
The auto_trim
plugin that ships with Vento has a specific implementation in the scope of this plugin. See Auto-Trimming Tags for more details._
If you'd like to extend the Vento library with any plugins, include them in an array passed to the plugins
option.
import { VentoPlugin } from 'eleventy-plugin-vento';
function myCustomPlugin() {
// ...plugin code...
}
export default function (eleventyConfig) {
eleventyConfig.addPlugin(VentoPlugin, {
plugins: [myCustomPlugin],
});
}
One exception to Vento plugins is the autoTrim
plugin which is bundled with Vento, and by extension, this plugin. This plugin provides a convenient way to control whitespace in the output by collapsing spaces left behind when Vento's tags are removed.
To trim space around the default tags and all Eleventy paired shortcodes, set the autotrim
plugin option to true
.
eleventyConfig.addPlugin(VentoPlugin, {
autotrim: true,
});
The default set of tags that are trimmed are defined by Vento itself. To set your own list of tags, set autotrim
to an array of tags:
eleventyConfig.addPlugin(VentoPlugin, {
autotrim: ['set', 'if', 'for'],
});
If instead, you'd like to extend instead of replace the default tag list, add the value @vento
and/or @11ty
. These placeholders will expand to the Vento default tags and Eleventy paired shortcode tags when the plugin executes.
import { VentoPlugin } from 'eleventy-plugin-vento';
eleventyConfig.addPlugin(VentoPlugin, {
autotrim: {
tags: ['@vento', '@11ty', 'tag'],
},
});
Vento: See Auto Trim Plugin.
Like Eleventy, this plugin uses the debug
package to handle verbose logging. The following DEBUG
namespaces are implemented:
Eleventy:Vento
- Logs initial setup of the plugin, loading features, pre-page compile setup steps (like changingpage
andeleventy
objects)Eleventy:Vento:Cache
- Logs updates to Vento's own internal cache, which is used in tandem with Eleventy's cache.Eleventy:Vento:Render
- Logs when templates are rendered
Because it is a child of the Eleventy:
namespace, the following command will include output from this plugin as well:
$ DEBUG='Eleventy:*' npx @11ty/eleventy
Alternatively, use a finer grained namespace to see only the output generated by eleventy-plugin-vento
.
$ DEBUG='Eleventy:Vento*' npx @11ty/eleventy
$ DEBUG='Eleventy:Vento:Template' npx @11ty/eleventy
Eleventy: See Debug Mode.
Debug: See debug
on npm.