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.5
- Booleans:
True, False, Nil
- Symbols (treated as strings):
:value
- Arrays of the above:
['a', 'b']
- Hashes of the above:
{ id: 1, role: 'main' }
| %input{type: :text, name: 'email'}
%a{href: "/", class: 'home'} Home
|
To 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} click
|
The 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} go
|
If $attrs<href> is /from-splat, the rendered href is /from-splat.
Reverse the order to make the literal win:
| %a{|$attrs, href: '/wins'} go
|
Multiple 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} hi
|
With $h<class> set to 'c', the rendered class is 'b c a' (literal and
splat in declaration order, shorthand classes appended).
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:
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));
|