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-each directive with new and improved ht-each='item in ${ variable }' syntax.

    Learn more
  • Added new hyperctl theme migrate command 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-pipe directive to pull-based ht-pipe='from "selector"' expressions.

    BONUS: ht-pipe directives now deduplicate piped contents!

    Learn more
  • BREAKING: removed the ht-template in favor of the ht-each directive.

    Learn more
  • BREAKING: removed the ht-not directive in favor of a more expressive ht-if directive.

    You could already express ht-not='${ page.foo }==bar' as ht-if='${ page.foo } != "bar"', but as of v0.23.0 you can now also replace ht-not='${ page.foo }' with ht-if='!${ page.foo }' thanks to the new ! unary operator.

    Learn more
  • BREAKING: removed the ht-content directive in favor of using ht-apply for content templating.

    Learn more
  • BREAKING: removed the ht-attr directive in favor of using ht-apply for attribute templating;

    NOTE: ht-attrs (plural) is still supported, but only for attribute maps.

    Learn more
  • BREAKING: removed the ht-query directive in favor of using [ht-apply] for URL attribute string interpolation.

    Learn more
  • BREAKING: removed the ht-param directive 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.Page attachments to Atom entry links.

    Link attachments become rel="related" links, and image-, audio-, video-, document-, and file- attachments become rel="enclosure" links (see RFC 4287 section 4.2.7.2. The "rel" Attribute).

    Learn more
  • Added support for .deploymentignore files.

    Builds can now include additional files in build outputs (e.g. build.log and build.json).

    Learn more
  • Added new --data-file flag to hyperctl build, hyperctl deploy, and hyperctl dev server.

    Use hyperctl build --log-file=build.json to capture build results in build outputs.

    Learn more
  • Added new --log-file flag to hyperctl build, hyperctl deploy, and hyperctl dev server.

    Use hyperctl build --log-file=build.log to capture build logs in build outputs.

    Learn more
  • Combined hyperctl build complete and hyperctl build incremental into a single hyperctl build command.

    Learn more
  • Combined hyperctl deploy complete and hyperctl deploy incremental into a single hyperctl deploy command.

    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


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 setting draft:true in page data files. This release also changes template data namespace names which are now derived from their file path.

CHANGES


  • Added a new ht-apply directive 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 new git provider.

     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_KEY
    
    Learn more
  • Added a new site.environments setting for configuring named hosting environments, consisting of one or more providers:

    1environments:
    2  production: [cloudflare_r2]
    3  staging: [github]
    
    Learn more
  • Added page.ugly_url so pages can generate <path>.html pages instead of <path>/index.html pages.

    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 ls to enumerate the full build context instead of just website data.

  • Changed hyperctl cms data inspect <namespace> to hyperctl 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 data commands to support --verbose and -v flags. Computed namespace console output is silenced by default in hyperctl cms data commands. Use --verbose to route console output to stderr.

  • Changed all --config / -c arguments to use a default value of site.yaml.

  • Fixed build, deploy, and dev server commands to honor site.config.builds_dir when constructing build output paths.

  • Fixed an infinite loop that could during builds with multiple feeds.

  • Removed site.config.drafts_dir setting 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, and site.assets to template data
  • Added page.* template data to ht-block
  • Added support for template data array accessors (e.g. page.attachments.1.kind)
  • Added support for ht-block user data
  • Improved markdown detection of inline vs block-level ht-block elements
    NOTE: block-level ht-block elements 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.username field for backwards compatibility with very early versions of hyperctl
  • Fixed a race condition in hyperctl dev server that 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)

hyperctl v0.18.0 (2026-02-26)

💬 Join the community

Stay up-to-date with the latest releases and other news from the Team behind HyperTemplates. Ask the developers questions, get help from the community, and share your creations! 🎨