Changelog
hyperctl v0.23.0 (2026-08-04)
NEW: hyperctl version 0.23.0 with simplified set of templating directives, and a hyperctl theme migrate command to help with migrating legacy directives.
In hyperctl version 0.23.0 we managed to add several new features while reducing the total number of template directives by 38.5% (from 13 to 8). The five (!) removed directives are all obviated by the expressivenes of the new ${ ... } template variables system introduced in v0.20.0. It's now possible to develop most websites use only five templating directives: ht-include, ht-if, ht-each, ht-apply, and ht-block.
CHANGES
-
Added new
ht-eachdirective with new and improvedht-each='item in ${ variable }'syntax.Learn more -
Added new
hyperctl theme migratecommand with idempotent migration of legacy directives.Learn more -
BREAKING: changed the template variable function invocation syntax to use parenthetical argument lists.
Learn more -
BREAKING: changed the CSS template variable syntax from
--ht-value(...)to--ht-var(...).Learn more -
BREAKING: changed
ht-pipedirective to pull-basedht-pipe='from "selector"'expressions.BONUS:
ht-pipedirectives now deduplicate piped contents!Learn more -
BREAKING: removed the
ht-templatein favor of theht-eachdirective.Learn more -
BREAKING: removed the
ht-notdirective in favor of a more expressiveht-ifdirective.You could already express
ht-not='${ page.foo }==bar'asht-if='${ page.foo } != "bar"', but as of v0.23.0 you can now also replaceht-not='${ page.foo }'withht-if='!${ page.foo }'thanks to the new!unary operator.Learn more -
BREAKING: removed the
ht-contentdirective in favor of usinght-applyfor content templating.Learn more -
BREAKING: removed the
ht-attrdirective in favor of usinght-applyfor attribute templating;NOTE:
ht-attrs(plural) is still supported, but only for attribute maps.Learn more -
BREAKING: removed the
ht-querydirective in favor of using [ht-apply] for URL attribute string interpolation.Learn more -
BREAKING: removed the
ht-paramdirective in favor of using [ht-apply] with template variables for string interpolation.Learn more
hyperctl v0.22.0 (2026-06-03)
NEW: hyperctl version 0.22.0 streamlines the hyperctl build and hyperctl deploy commands, adds support for build logs, and improves handling of page attachments in generated Atom feeds.
CHANGES
-
Added support for converting
hypertexting.Pageattachments to Atom entry links.Link attachments become
rel="related"links, and image-, audio-, video-, document-, and file- attachments becomerel="enclosure"links (see RFC 4287 section4.2.7.2. The "rel" Attribute).Learn more -
Added support for
.deploymentignorefiles.Builds can now include additional files in build outputs (e.g.
build.logandbuild.json).Learn more -
Added new
--data-fileflag tohyperctl build,hyperctl deploy, andhyperctl dev server.Use
hyperctl build --log-file=build.jsonto capture build results in build outputs.Learn more -
Added new
--log-fileflag tohyperctl build,hyperctl deploy, andhyperctl dev server.Use
hyperctl build --log-file=build.logto capture build logs in build outputs.Learn more -
Combined
hyperctl build completeandhyperctl build incrementalinto a singlehyperctl buildcommand.Learn more -
Combined
hyperctl deploy completeandhyperctl deploy incrementalinto a singlehyperctl deploycommand.Learn more
hyperctl v0.21.0 (2026-05-27)
NEW: hyperctl v0.21.0 adds support for file-based secrets and drops the git provider ssh_key_path secret.
CHANGES
- Added support for reading secrets from a new files secret provider.
hyperctl v0.20.0 (2026-05-12)
NEW: hyperctl v0.20.0 is a substantial release that adds support for a new ht-apply directive, template variables, templating plugins (!), computed template data, git-based hosting providers, multi-provider hosting environments, and more.
BREAKING: hyperctl v0.20.0 drops support for the
site.config.drafts_dir– drafts are now defined by settingdraft:truein page data files. This release also changes template data namespace names which are now derived from their file path.
CHANGES
-
Added a new
ht-applydirective to perform variable substitution. HyperTemplates now supports${ ... }variables, which can be used in element attributes and element text nodes.1<head> 2 <title ht-apply>${ site.title, "Default Title" } – ${ page.title, "✱" }</title> 3 <meta ht-apply name='description' content='${ page.description, "Placeholder Description" }'> 4</head>Learn more -
Added support for a
--ht-value( ... )variable substitution in layout<style>elements.1<head> 2 <style id='components' ht-pipe='from "style.component" as css'></style> 3 <style id='layout' ht-apply> 4 :root { 5 --color-1: --ht-value("page.colors.primary,site.colors.primary", rgba(236, 120, 184, 1.0)); 6 } 7 </style> 8</head>Learn more -
Added support for extending HyperTemplates with plugins, including template variable plugins, and computed namespace plugins. A plugin is a Javascript file that exports a default function, accepts positional arguments, and has access to predefined local bindings.
data/tags.js 1// tags.js generates a data.tags object of unique website tags w/ tag counts 2// example output: {"html":{"count":3,"label":"HTML"},"css":{"count":1,"label":"CSS"},"rss":{"count":4,"label":"RSS"}} 3export default function tagcloud() { 4 var result = {} 5 for (let page of site.pages) { 6 let tags = page.tags || [] 7 console.log(`${ page.path } has ${ tags.length } tags`) 8 for (let tag of tags) { 9 let id = tag.toLowerCase(); 10 result[id] = (result[id] || { label: tag, count: 0 }) 11 result[id].count += 1 12 } 13 } 14 return result 15};Learn more -
Added builtins for providing automated templating features powered by layout fragments. Builtins can be disabled and/or overriden by adding layout fragments to your theme.
Learn more -
Added new
site.providers(plural) setting for configuring named providers, and HyperTemplates now supports git-based hosting services using the newgitprovider.1providers: 2 cloudflare_r2: 3 kind: s3 4 endpoint: https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.cloudflarestorage.com 5 config: 6 bucket: my-website 7 secrets: 8 - name: access_key_id 9 key: AWS_ACCESS_KEY_ID 10 - name: secret_access_key 11 key: AWS_SECRET_ACCESS_KEY 12 github: 13 kind: git 14 endpoint: [email protected]:herdworks/hypertemplates-web.git 15 config: 16 branch: gh-pages 17 publish_dir: public 18 exclude: 19 paths: 20 - '\.tar\.gz$' 21 secrets: 22 - name: ssh_private_key 23 key: GH_DEPLOY_KEYLearn more -
Added a new
site.environmentssetting for configuring named hosting environments, consisting of one or more providers:1environments: 2 production: [cloudflare_r2] 3 staging: [github]Learn more -
Added
page.ugly_urlso pages can generate<path>.htmlpages instead of<path>/index.htmlpages.Learn more -
Added support for CSV template data files. Delimited data must contain a header row, and header rows must have unique non-empty column names.
Learn more -
Changed
hyperctl cms data lsto enumerate the full build context instead of just website data. -
Changed
hyperctl cms data inspect <namespace>tohyperctl cms data inspect <keypath>. Accepts template data keypaths (e.g.site.pages,data.social.twitter) instead of only top-level namespaces – extremely useful for developing computed namespaces! -
Changed
hyperctl cms datacommands to support--verboseand-vflags. Computed namespaceconsoleoutput is silenced by default inhyperctl cms datacommands. Use--verboseto routeconsoleoutput to stderr. -
Changed all
--config/-carguments to use a default value ofsite.yaml. -
Fixed build, deploy, and dev server commands to honor
site.config.builds_dirwhen constructing build output paths. -
Fixed an infinite loop that could during builds with multiple feeds.
-
Removed
site.config.drafts_dirsetting and loading of pages from a drafts directory.
hyperctl v0.19.0 (2026-04-21)
NEW: hyperctl version v0.19.0 adds support for site.pages, site.drafts, and site.assets template data,
and brings several improvements to ht-block elements, including access to page.* template data from ht-block templates.
- Added
site.pages,site.drafts, andsite.assetsto template data - Added
page.*template data toht-block - Added support for template data array accessors (e.g.
page.attachments.1.kind) - Added support for
ht-blockuser data - Improved markdown detection of inline vs block-level
ht-blockelements
NOTE: block-levelht-blockelements should no longer be wrapped in<p>tags. - Improved markdown detection of
<!--more-->comments (now allows whitespace variants, e.g.<!-- more -->)
hyperctl v0.18.2 (2026-04-12)
- Added
byline.usernamefield for backwards compatibility with very early versions ofhyperctl - Fixed a race condition in
hyperctl dev serverthat would cause the server to crash intermittently - Fixed a bug that generated broken URLs in Atom feed
<link rel='self'>elements; we're not properly joining "atom.xml" instead of concatenating "atom.xml" to page paths
hyperctl v0.18.1 (2026-03-01)
- Fixed
hyperctl theme packagenow includes thetheme.jsonconfiguration file in the generated theme archive.
hyperctl v0.18.0 (2026-02-26)
- Added
ht.*template data namespace, andht.version&ht.release_dateproperties - Added
env.*template data namespace (forHT_*environment variables) - Added
theme.*template data namespace – themes can now provide default template data - Added
block.*template data namespace forht-blockelements - Added
page.canonical_urlcomputed property (equivalent tosite.base_url+page.path) - Added
ht-offsetandht-limitparameters for configuringht-templateiterators - Added
hyperctl theme ls,hyperctl theme install, andhyperctl theme packagecommands - Added
theme.config.fragments_dirandtheme.config.data_dirconfiguration settings - Added HyperMark word count extension, computes a
page.wordcountproperty for parsed Markdown documents - Added support for
page.md,page.yaml, andpage.jsonpage files - Added support for "static" pages, created via
index.htmlorpage.htmlfiles (e.g.content/**/index.html) - Added support for
ht-attrsmaps, mapping template data keys to element attribute names - Changed
site.author→site.byline - Changed
page.author→page.byline - Changed
hyperctl new→hyperctl cms new - Changed
hyperctl asset→hyperctl cms asset - Changed
hyperctl content-type→hyperctl cms content-type - Changed
hyperctl data→hyperctl cms data - Changed
hyperctl page→hyperctl cms page - Changed
hyperctl build→hyperctl build complete - Changed
hyperctl generate→hyperctl build incremental - Changed
hyperctl deploy→hyperctl deploy complete - Changed
hyperctl publish→hyperctl deploy incremental - Changed
hyperctl graph→hyperctl dev graph - Changed
hyperctl mimetype→hyperctl dev mimetype - Changed
hyperctl render→hyperctl dev render - Changed
hyperctl server→hyperctl dev server - Removed
data.env.*template data in favor of newenv.*namespace - Removed
data.ht.*template data in favor of newht.*namespace - Removed
page.author.username(what would have becomepage.byline.username) - Removed
page.contributors[*].username(contributors have the same properties as apage.byline)