Skip to content

Commit

Permalink
Improved HTML attribute handling
Browse files Browse the repository at this point in the history
  • Loading branch information
joshmcrae committed Sep 8, 2024
1 parent da564d4 commit 48d4f9b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
10 changes: 10 additions & 0 deletions docs/views.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ e::form(
);
```

In some situations it may be convenient to conditionally concatenate a list of
strings to form an attribute value, e.g. on the `class` attribute. For this
reason, attributes with array values are interpretted in a special way. Array
elements with a numeric index are concatenated unconditionally, whereas string
indices are concatenated if their associated value is truthy.

```php
e::input(type: 'text', class: ['p-4 rounded-lg border-1', 'border-slate-300' => !$error, 'border-slate-500' => $error]);
```

Underscores in attribute names are automatically converted to hyphens. In some
cases, more complex attribute names are needed. For example, you may be using
a front end library that understands attributes in the form of `:bind` and `@click`.
Expand Down
23 changes: 22 additions & 1 deletion src/View/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,28 @@ public function __toString(): string
// Render attributes
foreach ($this->attributes as $name => $value) {
$name = strtolower(str_replace('_', '-', $name));
$str .= sprintf(' %s="%s"', $name, htmlspecialchars($value));

if (is_array($value)) {
$values = [];

foreach ($value as $k => $v) {
if (is_string($k)) {
if (boolval($v)) {
$values[] = $k;
}
} else {
$values[] = $v;
}
}

$value = implode(' ', $values);
}

if (is_bool($value)) {
$str .= ' ' . $name;
} else {
$str .= sprintf(' %s="%s"', $name, htmlspecialchars($value));
}
}

if ($this->isVoid) {
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/View/ElementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ public function testAttributeCase()
$this->assertEquals('<div x-show="open"></div>', (string) $el);
}

public function testAttributeBoolean()
{
$el = new Element('button', false, disabled: true);

$this->assertEquals('<button disabled></button>', (string) $el);
}

public function testAttributeArray()
{
$el = new Element('div', false, class: ['p-4 border-1', 'border-slate-300' => false, 'border-red-500' => true]);

$this->assertEquals('<div class="p-4 border-1 border-red-500"></div>', (string) $el);
}

public function testInnerText()
{
$el = new Element('p', false, 'Hello, world!<br/>');
Expand Down

0 comments on commit 48d4f9b

Please sign in to comment.