Skip to content

Commit d5a807c

Browse files
committed
Update attributes.md
1 parent 9f2dfcd commit d5a807c

File tree

1 file changed

+144
-11
lines changed

1 file changed

+144
-11
lines changed

handbook/attributes.md

+144-11
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,157 @@
11
# Attributes deep dive
22

3-
You’ve just rebuilt 90% of Phlex so you know a thing or two about rendering attributes.
3+
You’ve just rebuilt 90% of Phlex so you know a thing or two about rendering attributes, right?
4+
5+
In the previous example, we rendered attributes like this:
6+
7+
```ruby
8+
attributes.each do |key, value|
9+
@buffer << " #{key}=\"#{value}\""
10+
end
11+
```
412

513
## Keys
614

7-
- Difference between string and symbol keys
15+
If you use symbols for keys, Phlex will replace underscores `_` with dashes `-`. This is because the convention in HTML is to use dashes, while on the Ruby side, dashes are not allowed in symbols.
16+
17+
If you need to keep an underscore in the attribute name, you can use a string instead:
818

9-
## Values
19+
::: code-group
1020

11-
- Strings
12-
- Arrays
13-
- Sets
14-
- Booleans
15-
- Custom objects
21+
```ruby [component]
22+
h1(data_controller: "hello") { "Hello!" }
23+
h1("data_controller" => "hello") { "Hello!" }
24+
```
25+
26+
```html [output]
27+
<h1 foo-bar="hello">👋 Hello World!</h1>
28+
<h1 foo_bar="hello">👋 Hello World!</h1>
29+
```
30+
31+
:::
1632

1733
## Nested attributes
1834

19-
- Describe how hashes work
35+
You can nest attributes by using a hash as the value. The hash will be flattened with a dash between each level:
36+
37+
::: code-group
38+
39+
```ruby [component]
40+
h1(data: { controller: "hello" }) { "Hello!" }
41+
```
42+
43+
```html [output]
44+
<h1 data-controller="hello">👋 Hello World!</h1>
45+
```
46+
47+
:::
48+
49+
## Attribute values
50+
51+
You’ve seen how string values work. Symbols behave the same way. You’ve also seen how to nest attributes with hashes. But Phlex allows a few other types of attribute value.
52+
53+
### Arrays and sets
54+
55+
::: code-group
56+
57+
```ruby [component]
58+
h1(class: ["foo", "bar"]) { "Hello!" }
59+
h1(class: Set["foo", "bar"]) { "Hello!" }
60+
```
61+
62+
```html [output]
63+
<h1 class="foo bar">Hello!</h1>
64+
<h1 class="foo bar">Hello!</h1>
65+
```
66+
67+
:::
68+
69+
### Booleans
70+
71+
Booleans are a special case. If the value is `true`, Phlex will render the attribute without a value. If the value is `false`, Phlex will not render the attribute at all.
72+
73+
::: code-group
74+
75+
```ruby [component]
76+
textarea(disabled: true)
77+
textarea(disabled: false)
78+
```
79+
80+
```html [output]
81+
<textarea disabled></textarea> <textarea></textarea>
82+
```
83+
84+
:::
85+
86+
::: tip
87+
Some HTML attributes such as `contenteditable` require you to pass `"true"` or `"false"` as a string. These are not technically “boolean” attributes, they're “enumerated” attributes. The distinction is subtle but important.
88+
89+
:::
2090

2191
## Special attributes
2292

23-
- `style`
24-
- `class`
93+
### `class`
94+
95+
The `class` attribute is special. It behaves differently when you pass a Hash as a value, allowing you to conditionally add classes. Here, the class `active` is added because `is_active` is _truthy_, and the class `disabled` is not added because `is_disabled` is _falsy_:
96+
97+
::: code-group
98+
99+
```ruby [component]
100+
is_active = true
101+
is_disabled = false
102+
103+
a(class: { active: is_active, disabled: is_disabled }) { "Click me" }
104+
```
105+
106+
```html [output]
107+
<a class="active">👋 Hello World!</a>
108+
```
109+
110+
:::
111+
112+
You can also use this with an array:
113+
114+
::: code-group
115+
116+
```ruby{6} [component]
117+
is_active = true
118+
is_disabled = false
119+
120+
a(
121+
class: [
122+
"button",
123+
"active" => is_active,
124+
"disabled" => is_disabled
125+
]
126+
) { "Click me" }
127+
```
128+
129+
```html [output]
130+
<a class="button active">👋 Hello World!</a>
131+
```
132+
133+
In this example, the `button` class is always added, while the `active` and `disabled` classes are conditional. You can read `=>` as “if”.
134+
135+
### `style`
136+
137+
Like `class`, the `style` attribute has special behaviour. If you pass a Hash to `style`, Phlex will convert it to a CSS string:
138+
139+
::: code-group
140+
141+
```ruby [component]
142+
h1(style: { color: "red", font_size: "16px" }) { "Hello!" }
143+
```
144+
145+
```html [output]
146+
<h1 style="color: red; font-size: 16px;">Hello!</h1>
147+
```
148+
149+
:::
150+
151+
### `href` on an `<a>` tag
152+
153+
It’s worth noting here that Phlex will not allow you to set the `href` attribute to anything that begins with `javascript:`. This is a security feature to prevent cross-site-scripting (XSS) attacks.
154+
155+
## Event attributes
156+
157+
Event attributes such as `onclick` are disallowed to prevent cross-site-scripting (XSS) attacks.

0 commit comments

Comments
 (0)