ht-attrs directive reference

Overview


The ht-attrs directive sets one or more HTML element attributes from provided template data objects.

NOTE: the ht-attrs directive enables an advanced templating technique called attribute mapping. For simple HTML attribute templating, see the ht-apply directive.

Example


The ht-attrs directive is most effective when paired with the ht-each directive. The following example shows how the ht-attrs directive can being used to configure <link> elements.

1<link ht-each='link in ${ site.links }' ht-attrs='${ link }'>

This template will generate <link> elements with attributes defined as template data key:value pairs. The ht-attrs directive is especially useful for templating collections of objects that have inconsistent contents. For example, in the following template data site.links collection, only one item has a sizes property:

1{
2  site: {
3    links: [
4      { rel: "icon", href: "/img/favicon.png" },
5      { rel: "apple-touch-icon", href: "/img/apple-touch-icon.png", sizes: "180x180" }
6    ]
7  }
8}

Given the example template provided above, this data would result in the following two <link> elements:

1<link rel='icon' href='/img/favicon.png'>
2<link rel='apple-touch-icon' href='/img/apple-touch-icon.png' sizes='180x180'>

Specification


Supported elements


The ht-attrs directives can be used with any HTML element.

1<a ht-attrs='${ link }'></a>

Directive syntax


The ht-attrs directive accepts a single template variable argument that resolves to a template data object containing key:value pairs.

1<meta ht-each='metadata in ${ site.metadata }' ht-attrs='${ metadata }'>

Default values


The ht-attrs directive will only cause attributes to be added to a target element if the specified template data property exists. In cases where no value exists, HyperTemplates ignores the attribute.

In scenarios where a default or fallback value is desired, simply set the element attribute in the template.

1<nav>
2  <menu>
3    <li ht-each='link in ${ data.nav.links }'>
4      <a ht-apply ht-attrs='${ link }' href='#'>${ link.text, "Placeholder" }</a>
5    </li>
6  </menu>
7</nav>

Attribute maps


The ht-attrs directive resolves [template variables] to template data objects and sets one HTML attribute per template data key. This approach is referred to as "attribute maps".

NOTE: attribute maps are syntactic sugar – an advanced templating feature for experienced template developers. They are great for simplifying template development, but they can add contextual complexity for template contributors – even if the contributor in question is the template author's future self. πŸ˜΅β€πŸ’«

Example

To illustrate, consider the following example page:

content/blog/introducing-hypertemplates/page.md
 1---
 2created_at: 2025-06-12T08:00:00-07:00
 3layout: post
 4title: Introducing HyperTemplates
 5description: |
 6    The pure-HTML templating system for the modern web.
 7cover: cover-light.png
 8metadata:
 9  - name: "twitter:card"
10    content: "summary_large_image"
11  - name: "twitter:site"
12    content: "@herdworks"
13  - name: "twitter:title"
14    content: "Introducing, HyperTemplates"
15  - property: "og.type"
16    content: "article"
17  - property: "og.title"
18    content: "Introducing, HyperTemplaes"
19  - property: "og.description"
20    content: "The pure-HTML templating system for the modern web."
21  - property: "og.url"
22    content: "https://hypertemplates.net/blog/introducing-hypertemplates/"
23  - property: "og.image"
24    content: "https://hypertemplates.net/blog/introducing-hypertemplates/cover-light.png"

Before template data maps, a template fragment to render these Twitter Card and OpenGraph metadata properties might have looked like this:

1<!-- Iterate over page.metadata properties and create <meta> elements for each property -->
2<meta ht-each='metadata in ${ page.metadata }' name='${ metadata.name }' property='${ metadata.property }' content='${ metadata.content }' />

With template data maps, that same template fragment can be simplified to the following:

1<!-- Iterate over page.metadata properties and create <meta> elements for each property -->
2<meta ht-each='metadata in ${ page.metadata }' ht-attrs='${ metadata }' />

The resulting output for both templates would be as follows:

1<!-- Iterate over page.metadata properties and create <meta> elements for each property -->
2<meta name='twitter:card' content='summary_large_image' />
3<meta name='twitter:site' content='@herdworks' />
4<meta name='twitter:title' content='Introducing, HyperTemplates' />
5<meta property='og.type' content='article' />
6<meta property='og.title' content='Introducing, HyperTemplaes' />
7<meta property='og.description' content='The pure-HTML templating system for the modern web.' />
8<meta property='og.url' content='https://hypertemplates.net/blog/introducing-hypertemplates/' />
9<meta property='og.image' content='https://hypertemplates.net/blog/introducing-hypertemplates/cover-light.png' />

πŸ’¬ 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! 🎨