ht-attrs directive reference
Overview
The ht-attrs directive sets one or more HTML element attributes from provided template data objects.
NOTE: the
ht-attrsdirective enables an advanced templating technique called attribute mapping. For simple HTML attribute templating, see theht-applydirective.
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:
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' />