Attributes

GoHT supports more than declaring an id or classes on an element. You can declare any attribute you need to on an element.

The attribute syntax is similar to the syntax for a Go map. You use curly braces {} to declare the attributes. Inside the curly braces, you have key-value pairs separated by a colon :. The key is the attribute name, and the value is the attribute value.

Basic Attributes

%a{href: "https://goht.dev", target: "_blank"} Learn about GoHT

renders as:

<a href="https://goht.dev" target="_blank">Learn about GoHT</a>

Complex Attribute Names

Attribute names can be complex. They can contain spaces, dashes, and other characters that are not valid in GoHT. Outside of dashes and underscores, to use any other character that is not alphanumeric, you can use a string.

%a{"@click": "clickHandler"} Do something with a click!

renders as:

<a @click="clickHandler">Do something with a click!</a>

Dynamic Attribute Values

You can also use Go to create dynamic attribute values using the same interpolation syntax as you would for Go evaluation.

- url := "https://goht.dev"
%a{href: #{url}, target: "_blank"} Learn about GoHT

renders as:

<a href="https://goht.dev" target="_blank">Learn about GoHT</a>

Boolean Attributes

Boolean attributes are attributes that do not require a value. They are either present or not. To include a boolean attribute, you can do it one of two ways. The first is to simply include the attribute name in the attribute list.

%input{disabled, "@click": "clickHandler"} Click me!

renders as:

<input disabled @click="clickHandler">

The second is to include the attribute name with an interpolated value. If that value evaluates to true at render time, the attribute will be included. We use a question mark ? in place of the colon : to indicate that the attribute is a boolean attribute.

- disabled := true
%input{disabled? #{disabled}, "@click": "clickHandler"} Click me!

renders as:

<input disabled @click="clickHandler">

Classes

The class attribute is a special type of attribute. There are multiple sources of classes, and you may want to add classes in one case but not another. It gets complicated quickly. GoHT provides multiple ways to add classes to an element.

Class Attribute

We’ve already seen the period . syntax for adding classes. You can also use the class attribute to add classes.

%div.outer{class: "container"}
  %span This span is contained!

renders as:

<div class="outer container">
  <span>This span is contained!</span>
</div>

Multiple Classes

An interpolated string value can be used to add multiple classes.

- classes := "container wrapper"
%div.outer{class: #{classes}}
  %span This span is contained and wrapped!

renders as:

<div class="outer container wrapper">
  <span>This span is contained and wrapped!</span>
</div>

Multiple Classes with a Slice

The interpolated value can also be a slice of strings to add multiple classes.

- classes := []string{"container", "wrapper"}
%div.outer{class: #{classes}}
  %span This span is contained and wrapped!

renders as:

<div class="outer container wrapper">
  <span>This span is contained and wrapped!</span>
</div>

Conditional Classes

You can also use the class attribute with a map of strings keys to boolean values to add multiple classes conditionally.

- classes := map[string]bool{"container": true, "wrapper": false}
%div.outer{class: #{classes}}
  %span This span is contained and wrapped!

renders as:

<div class="outer container">
  <span>This span is contained and wrapped!</span>
</div>

Combining Class Sources

And all three can be combined.

- classes := []string{"container", "wrapper"}
- conditionalClasses := map[string]bool{"foo": true, "bar": false}
%div.outer{class: #{"main", classes, conditionalClasses}}
  %span This span is contained and wrapped!

renders as:

<div class="outer main container wrapper foo">
  <span>This span is contained and wrapped!</span>
</div>

Dynamic Attributes

GoHT also provides an easy way to add dynamic attributes to an element. You can use the @attributes directive to add a map of attributes to an element. The directive requires the use of an interpolated value. It accepts a list of attributes in two forms. The first is a map of strings to strings which represent attribute names and values, and the second is a map of strings to boolean values which represent attribute names and whether the attribute should be included.

- attributes := map[string]string{"href": "https://goht.dev", "target": "_blank"}
%a{@attributes: #{attributes}} Learn about GoHT

renders as:

<a href="https://goht.dev" target="_blank">Learn about GoHT</a>

Both kinds of maps can be used together.

- attributes := map[string]string{"href": "https://goht.dev", "target": "_blank"}
- booleanAttributes := map[string]bool{"disabled": true, "hidden": false}
%a{"@click": "clickHandler", @attributes: #{attributes, booleanAttributes}} Learn about GoHT

renders as:

<a @click="clickHandler" href="https://goht.dev" target="_blank" disabled>Learn about GoHT</a>