Haml 6 was a major rewrite Show archive.org snapshot with performance in mind. To achieve a performance improvement of 1.7x, some design trade-offs had to be made. The most notable change might be the simplified attribute rendering.
In Haml 5, attribute rendering knew two special cases: an attribute with value true
would be rendered without a value, an attribute with a falsy value would not be rendered at all. All other values would just be rendered as attribute values.
According to the Haml maintainer, this negatively impacted rendering performance Show archive.org snapshot . So in Haml 6, they kept this behavior only for a few attributes Show archive.org snapshot , which they called "boolean". All other attributes will just render their value as it is given.
Behavior of "boolean attributes" remains unchanged
- No Haml value => no HTML value
- Boolean Haml value => attribute is rendered depending on that value
- All other values => rendered verbatim
Haml | HTML generated by Haml 5 & 6 |
---|---|
%button(disabled) | <button disabled></button> |
%button(disabled=true) | <button disabled></button> |
%button(disabled=false) | <button></button> |
%button(disabled=nil) | <button></button> |
%button(disabled='123') | <button disabled='123'></button> |
Other attributes will be handled differently by Haml 6
New: custom attributes will always render an HTML value. They are not toggled by their value. In other words: only write an attribute in Haml if you want it rendered.
To render a custom attribute without a value, you can either:
- Assign an empty string (
custom-attribute=''
) - Use a
data-
attribute (data-custom-attribute
) – recommended for attributes that actually convey data - Or add the custom attribute to the list of boolean attributes (see below)
Haml | HTML generated by Haml 5 | HTML generated by Haml 6 |
---|---|---|
%button(up-test) | <button up-test></button> |
<button up-test="true"></button> |
%button(up-test=true) | <button up-test></button> |
<button up-test="true"></button> |
%button(up-test=false) | <button></button> |
<button up-test="false"></button> |
%button(up-test=nil) | <button></button> |
<button up-test=""></button> |
%button(up-test='true') | <button up-test="true"></button> |
same |
%button(up-test='false') | <button up-test="false"></button> |
same |
%button(up-test='') | <button up-test=''></button> |
same |
Extending the list of attributes considered "boolean"
You can add to the list of "boolean attributes", but please do sparingly. Boolean attributes are rendered by less performant code, so each boolean attribute that appears in a view will slow down rendering a little bit.
# config/initializers/haml.rb
Haml::BOOLEAN_ATTRIBUTES.push(/^app-/)
Haml::BOOLEAN_ATTRIBUTES.push(*%w[one another])
Boolean ARIA and Unpoly Show archive.org snapshot attributes
Be very selective about adding up-
attributes so you can still use expressions like [aria-expanded=false]
or [up-follow=false]
without the attribute disappearing entirely.
Starting with
Unpoly 3.8
Show archive.org snapshot
, most Unpoly attributes can be enabled with a value "true"
and be disabled with a value "false"
. This pairs well with the default (unpatched) Haml 6 behavior.
A different approach is to create attributes from a ruby hash:
%tr{ { 'up-expand': ('' if superuser?) }.compact }
This will provide you with <tr up-expand="">
for a superuser and <tr>
otherwise.