attributes
Attributes
Template::HAML supports a Ruby-style attribute hash on any tag:
%a{href: '/about', title: 'About us'} About<a href='/about' title='About us'>About</a>Value types
Today the supported value types inside { ... } are:
Single-quoted strings:
'value'Double-quoted strings:
"value"(supports#{...}interpolation)Numbers:
123,-4.5Booleans:
True,False,NilSymbols (treated as strings):
:valueArrays of the above:
['a', 'b']Hashes of the above:
{ id: 1, role: 'main' }
%input{type: :text, name: 'email'}
%a{href: "/", class: 'home'} HomeTo embed a Raku local variable, use double-quoted interpolation or an
attribute splat ā never a bareword $var. A hash whose value the parser
cannot read raises X::HAML::ParseFail pointing at the opening {:
%a{href: "#{$url}"} go -- works (interpolation)
%a{|$attrs} go -- works (splat)
%a{href: $url} go -- X::HAML::ParseFail
%a{aria-label: 'home'} hi -- X::HAML::ParseFail (hyphen bareword key)Hyphenated keys must be quoted:
%a{'aria-label' => 'home'} hi
%a{"data-id" => 1} clickThe same rule applies to HTML-style (...) attrs: values must be quoted
strings; a $var value or any other unparseable construct raises
X::HAML::ParseFail.
Multiple attributes
Separate attributes with commas:
%a{href: '/', class: 'home', id: 'home-link'} Home<a href='/' class='home' id='home-link'>Home</a>Class shorthand merges with class:
The .classname shorthand on a tag merges with any class: entry in the attribute hash. The two forms compose:
%p.lead{class: 'intro'} Welcome<p class='lead intro'>Welcome</p>Multi-line attribute hashes
An attribute hash, an HTML-style attribute list, an array value, or a nested hash may span multiple lines. The tag does not close until the matching } (or )) is seen.
%a{
href: '/',
title: 'home'
}<a href='/' title='home'></a>Nested hashes and arrays may also span lines:
%a{
class: ['foo', 'bar'],
data: {
id: 1,
role: 'main'
}
}<a class='foo bar' data-id='1' data-role='main'></a>HTML-style attributes may also be split across lines:
%a(
href='/'
title='home'
)<a href='/' title='home'></a>Content and child indentation pick up after the closing brace:
%ul{
class: 'list'
}
%li one
%li two<ul class='list'>
<li>one</li>
<li>two</li>
</ul>Source line numbers are preserved across multi-line hashes, so children render and report at their actual line in the source.
Attribute splat (|$expr)
Prefix any expression inside { ... } with | to merge its result into the
tag's attributes:
HAML.render(
:src('%a{|$attrs} link' ~ "\n"),
:locals(%(attrs => %( :href('/'), :title('home') ))),
);<a href='/' title='home'>link</a>The splat expression is plain Raku. Locals are bound with the $ sigil, so
write |$attrs, |$obj.attrs, |$mk(), and so on. The expression must
evaluate to one of:
a
Hash(keys are emitted in alphabetical order),a single
Pair,a list of
Pairs (emitted in declaration order).
Composes with literal pairs
Splats interleave freely with literal key: value entries. Within a single
tag, later entries override earlier ones for the same key:
%a{href: '/from-literal', |$attrs} goIf $attrs<href> is /from-splat, the rendered href is /from-splat.
Reverse the order to make the literal win:
%a{|$attrs, href: '/wins'} goMultiple splats
%tag{|$a, |$b} is valid. Later splats override earlier ones for the same
non-class/non-id key.
class: and id: accumulate
Splatted class: values merge with shorthand classes and any literal class:
entry ā duplicates are removed and the result is space-joined. Splatted id:
values concatenate with shorthand ids and literal id: entries using _.
%div.a{class: 'b', |$h} hiWith $h<class> set to 'c', the rendered class is 'b c a' (literal and
splat in declaration order, shorthand classes appended).
%div#one{id: 'two', |$h}With $h<id> set to 'three', the rendered id is 'one_two_three'
(shorthand ids first, then literal and splat values in declaration order).
Nested hashes work too
Splatting a hash whose values include another hash under data: or aria:
expands into the same hyphenated attributes as a literal nested hash:
HAML.render(
:src('%a{|$h}' ~ "\n"),
:locals(%(h => %( :data({ :id(1), :role('main') }) ))),
);<a data-id='1' data-role='main'></a>data: / aria: hyphenation
By default, keys under data: and aria: hashes are emitted verbatim:
%a{data: {fooBar: 1}}<a data-fooBar='1'></a>Enable the hyphenate-data-attrs config option to convert
camelCase keys to kebab-case. The conversion is recursive ā every level
of a nested hash is rewritten:
my $cfg = Template::HAML::Config.new(:hyphenate-data-attrs);
HAML.render(:src('%a{data: {fooBar: 1}}' ~ "\n"), :config($cfg));<a data-foo-bar='1'></a>