Skip to content

Commit 972595c

Browse files
authored
fix(view): consume dynamic attributes (#644)
1 parent 52ca58d commit 972595c

File tree

5 files changed

+59
-19
lines changed

5 files changed

+59
-19
lines changed

src/Tempest/View/src/Element.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public function getAttribute(string $name): string|null;
1616

1717
public function setAttribute(string $name, string $value): self;
1818

19+
public function consumeAttribute(string $name): string|null;
20+
1921
public function setPrevious(?Element $previous): self;
2022

2123
public function getPrevious(): ?Element;

src/Tempest/View/src/Elements/IsElement.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ public function setAttribute(string $name, string $value): self
5353
return $this;
5454
}
5555

56+
public function consumeAttribute(string $name): string|null
57+
{
58+
$value = $this->getAttribute($name);
59+
60+
$this->unsetAttribute($name);
61+
62+
return $value;
63+
}
64+
5665
public function unsetAttribute(string $name): self
5766
{
5867
$name = ltrim($name, ':');

src/Tempest/View/src/Elements/PhpForeachElement.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ public function setElse(Element $element): self
3232

3333
public function compile(): string
3434
{
35+
$foreachAttribute = $this->wrappingElement->consumeAttribute('foreach');
36+
3537
$compiled = sprintf(
3638
'<?php foreach (%s): ?>
3739
%s',
38-
$this->wrappingElement->getAttribute('foreach'),
40+
$foreachAttribute,
3941
$this->wrappingElement->compile(),
4042
);
4143

@@ -47,8 +49,9 @@ public function compile(): string
4749
);
4850

4951
if ($this->else !== null) {
50-
$collectionName = str($this->wrappingElement->getAttribute('foreach'))
51-
->match('/^(?<match>.*)\s+as/')['match'];
52+
$collectionName = str($foreachAttribute)->match('/^(?<match>.*)\s+as/')['match'];
53+
54+
$this->else->consumeAttribute('forelse');
5255

5356
$compiled = sprintf(
5457
'<?php if(iterator_count(%s)): ?>

src/Tempest/View/src/Elements/PhpIfElement.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function compile(): string
4444
$compiled = sprintf(
4545
"<?php if(%s): ?>
4646
%s",
47-
$this->wrappingElement->getAttribute('if'),
47+
$this->wrappingElement->consumeAttribute('if'),
4848
$this->wrappingElement->compile(),
4949
);
5050

@@ -54,12 +54,14 @@ public function compile(): string
5454
<?php elseif(%s): ?>
5555
%s",
5656
$compiled,
57-
$elseif->getAttribute('elseif'),
57+
$elseif->consumeAttribute('elseif'),
5858
$elseif->compile(),
5959
);
6060
}
6161

6262
if ($this->else !== null) {
63+
$this->else->consumeAttribute('else');
64+
6365
$compiled = sprintf(
6466
"%s
6567
<?php else: ?>

tests/Integration/View/TempestViewRendererTest.php

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,58 +52,58 @@ public function test_if_attribute(): void
5252
);
5353

5454
$this->assertSame(
55-
'<div :if="$this->show">Hello</div>',
55+
'<div>Hello</div>',
5656
$this->render(view('<div :if="$this->show">Hello</div>')->data(show: true)),
5757
);
5858
}
5959

6060
public function test_elseif_attribute(): void
6161
{
6262
$this->assertSame(
63-
'<div :if="$this->a">A</div>',
63+
'<div>A</div>',
6464
$this->render(view('<div :if="$this->a">A</div><div :elseif="$this->b">B</div><div :else>None</div>')->data(a: true, b: true)),
6565
);
6666

6767
$this->assertSame(
68-
'<div :if="$this->a">A</div>',
68+
'<div>A</div>',
6969
$this->render(view('<div :if="$this->a">A</div><div :elseif="$this->b">B</div><div :else>None</div>')->data(a: true, b: false)),
7070
);
7171

7272
$this->assertSame(
73-
'<div :elseif="$this->b">B</div>',
73+
'<div>B</div>',
7474
$this->render(view('<div :if="$this->a">A</div><div :elseif="$this->b">B</div><div :else>None</div>')->data(a: false, b: true)),
7575
);
7676

7777
$this->assertSame(
78-
'<div :else>None</div>',
78+
'<div>None</div>',
7979
$this->render(view('<div :if="$this->a">A</div><div :elseif="$this->b">B</div><div :else>None</div>')->data(a: false, b: false)),
8080
);
8181

8282
$this->assertSame(
83-
'<div :elseif="$this->c">C</div>',
83+
'<div>C</div>',
8484
$this->render(view('<div :if="$this->a">A</div><div :elseif="$this->b">B</div><div :elseif="$this->c">C</div><div :else>None</div>')->data(a: false, b: false, c: true)),
8585
);
8686

8787
$this->assertSame(
88-
'<div :elseif="$this->b">B</div>',
88+
'<div>B</div>',
8989
$this->render(view('<div :if="$this->a">A</div><div :elseif="$this->b">B</div><div :elseif="$this->c">C</div><div :else>None</div>')->data(a: false, b: true, c: true)),
9090
);
9191

9292
$this->assertSame(
93-
'<div :else>None</div>',
93+
'<div>None</div>',
9494
$this->render(view('<div :if="$this->a">A</div><div :elseif="$this->b">B</div><div :elseif="$this->c">C</div><div :else>None</div>')->data(a: false, b: false, c: false)),
9595
);
9696
}
9797

9898
public function test_else_attribute(): void
9999
{
100100
$this->assertSame(
101-
'<div :if="$this->show">True</div>',
101+
'<div>True</div>',
102102
$this->render(view('<div :if="$this->show">True</div><div :else>False</div>')->data(show: true)),
103103
);
104104

105105
$this->assertSame(
106-
'<div :else>False</div>',
106+
'<div>False</div>',
107107
$this->render(view('<div :if="$this->show">True</div><div :else>False</div>')->data(show: false)),
108108
);
109109
}
@@ -112,25 +112,49 @@ public function test_foreach_attribute(): void
112112
{
113113
$this->assertStringEqualsStringIgnoringLineEndings(
114114
<<<'HTML'
115-
<div :foreach="$this->items as $foo">a</div>
116-
<div :foreach="$this->items as $foo">b</div>
115+
<div>a</div>
116+
<div>b</div>
117117
HTML,
118118
$this->render(view('<div :foreach="$this->items as $foo">{{ $foo }}</div>')->data(items: ['a', 'b'])),
119119
);
120120
}
121121

122+
public function test_foreach_consumes_attribute(): void
123+
{
124+
$html = $this->render(view(
125+
<<<'HTML'
126+
<x-base>
127+
<table>
128+
<tr :foreach="$items as $item">
129+
<td>{{ $item }}</td>
130+
</tr>
131+
</table>
132+
</x-base>
133+
HTML,
134+
)->data(items: ['a', 'b']));
135+
136+
$this->assertStringContainsStringIgnoringLineEndings(
137+
<<<'HTML'
138+
<html lang="en"><head><title>Home</title></head><body><table><tr><td>a</td></tr>
139+
<tr><td>b</td></tr>
140+
</table></body></html>
141+
HTML,
142+
$html
143+
);
144+
}
145+
122146
public function test_forelse_attribute(): void
123147
{
124148
$this->assertSame(
125149
<<<'HTML'
126-
<div :forelse>Empty</div>
150+
<div>Empty</div>
127151
HTML,
128152
$this->render(view('<div :foreach="$this->items as $foo">{{ $foo }}</div><div :forelse>Empty</div>')->data(items: [])),
129153
);
130154

131155
$this->assertSame(
132156
<<<'HTML'
133-
<div :foreach="$this->items as $foo">a</div>
157+
<div>a</div>
134158
HTML,
135159
$this->render(view('<div :foreach="$this->items as $foo">{{ $foo }}</div><div :forelse>Empty</div>')->data(items: ['a'])),
136160
);

0 commit comments

Comments
 (0)