Template Plugins
Overview
HyperTemplates plugins extend the capabilities of HyperTemplates with support for Javascript functions. A plugin is a Javascript file with a predefined entrypoint and local bindings that depend on the plugin type.
Examples
This is an example template variable plugins, which can accept one or more named arguments.
1// upper transforms strings to uppercase
2function plugin(input="") {
3 if (typeof input !== "string") { return input }
4 return input.toUpperCase()
5};
This is an example computed namespace plugin, which does not accept arguments but does have access local data bindings, including: ht.*, build.*, env.*, data.*, theme.*, and site.* template data (including the full site.pages sitemap):
1// The data.archive namespace organizes posts into a reverse-chronological map
2// that can be used to generate archive pages.
3//
4// example output: { "2026": {}, "2025": {}, "2024": {} }
5function namespace() {
6 var archive = {}
7 for (let page of site.pages) {
8 // iterate over pages, construct archive template data
9 }
10 return archive
11};
Specification
Plugin runtime environment
HyperTemplates plugins run in small, sandboxed JavaScript environments based on ECMAScript 5.1 with a handful of ES6+ additions (notably let, const, arrow functions, template literals, destructuring, and Promise).
Think of it as "JavaScript the programming language" without "JavaScript the browser."
HyperTemplates plugins can leverage plain functions, core Javascript types like objects and arrays, and standard built-ins including: Array, Object, JSON, Math, Date, String, Number, Map, Set, and regular expressions.
HyperTemplates plugins run in an isolated context with no shared state between invocations.
Plugin logging
HyperTemplates plugins have access to a console object, including console.log, console.info, console.warn, console.error, and console.debug.
All console.* methods write to standard output with a [scripting] prefix.
A console.logger(name) function returns a console-shaped object that prefixes its output with the provided name (i.e. [name] ) which is useful for debugging output from a specific plugin.
Example
1const logger = console.logger("archive.js")
2function namespace() {
3 var archive = {}
4 for (let page in site.pages) {
5 logger.log(`page: ${page.path}`) // example output: "[archive.js] page: /blog/hello-world/"
6 // do something
7 }
8 return archive
9}
Plugin identifiers
HyperTemplates plugin identifiers are derived via their file path and/or file name.
A computed namespace plugin at <data_dir>/archive.js is named archive.
A template variable plugin at <plugins_dir>/reverse.js is named reverse.
Plugin entrypoints
HyperTemplates plugins use predefined entrypoints to determine what code to run. An entrypoint is a named binding of type "function".
Examples
For example, computed namespace plugins must define a namespace binding.
Both of the following examples create a plugin called uppercase (created via the plugins/uppercase.js file).
In the first example the uppercase plugin entrypoint function is defined via a function declaration (i.e. function plugin(input="") { ... }).
1// uppercase transforms strings to uppercase
2function plugin(input="") {
3 if (typeof input !== "string") { return input }
4 return input.toUpperCase()
5};
In the second example the uppercase plugin entrypoint function is defined via a const declaration (const plugin = uppercase).
1// upper transforms strings to uppercase
2function uppercase(input="") {
3 if (typeof input !== "string") { return input }
4 return input.toUpperCase()
5};
6const plugin = uppercase;
Local variables
Plugins types
HyperTemplates currently supports two types of plugins:
- Template variable plugins
- Something something variable substitution functions something...
- Template data plugins
- Something somethign computed namespaces something...