Skip to content

Commit f93fb3d

Browse files
authored
fix(view): fix for compiling HTML documents that contain PHP (#922)
1 parent 1ba1629 commit f93fb3d

File tree

7 files changed

+52
-37
lines changed

7 files changed

+52
-37
lines changed

src/Tempest/View/src/Renderers/TempestViewCompiler.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
final readonly class TempestViewCompiler
1919
{
20-
public const string TOKEN_PHP_OPEN = '__TOKEN_PHP_OPEN__';
20+
public const string TOKEN_PHP_OPEN = '<!--TOKEN_PHP_OPEN__';
2121

22-
public const string TOKEN_PHP_SHORT_ECHO = '__TOKEN_PHP_SHORT_ECHO__';
22+
public const string TOKEN_PHP_SHORT_ECHO = '<!--TOKEN_PHP_SHORT_ECHO__';
2323

24-
public const string TOKEN_PHP_CLOSE = '__TOKEN_PHP_CLOSE__';
24+
public const string TOKEN_PHP_CLOSE = '__TOKEN_PHP_CLOSE-->';
2525

2626
public const array TOKEN_MAPPING = [
2727
'<?php' => self::TOKEN_PHP_OPEN,
@@ -33,8 +33,7 @@ public function __construct(
3333
private ElementFactory $elementFactory,
3434
private AttributeFactory $attributeFactory,
3535
private Kernel $kernel,
36-
) {
37-
}
36+
) {}
3837

3938
public function compile(string $path): string
4039
{
@@ -104,7 +103,12 @@ private function parseDom(string $template): HTMLDocument|NodeList
104103
},
105104
);
106105

107-
if ($template->startsWith(['<html', '<!DOCTYPE', '<!doctype'])) {
106+
$isFullHtmlDocument = $template
107+
->replaceRegex('/('.self::TOKEN_PHP_OPEN.'|'.self::TOKEN_PHP_SHORT_ECHO.')(.|\n)*?'.self::TOKEN_PHP_CLOSE.'/', '')
108+
->trim()
109+
->startsWith(['<html', '<!DOCTYPE', '<!doctype']);
110+
111+
if ($isFullHtmlDocument) {
108112
// If we're rendering a full HTML document, we'll parse it as is
109113
return HTMLDocument::createFromString($template->toString(), LIBXML_NOERROR | HTML_NO_DEFAULT_NS);
110114
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<x-index>
2-
Hello <?= $name ?? 'World' ?>!
2+
Hello {{ $name ?? 'World' }}!
33
</x-index>

tests/Fixtures/Views/withViewModel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
/** @var ViewModel $this */
66
?>
77

8-
ViewModel <?= $this->name ?>, <?= $this->currentDate() ?>
8+
ViewModel {{ $this->name }}, {{ $this->currentDate() }}

tests/Integration/View/TempestViewRendererDataPassingTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ public function test_expression_attribute_in_raw_element(): void
280280

281281
$this->assertStringEqualsStringIgnoringLineEndings(
282282
<<<'HTML'
283-
<div><pre data-lang="php"><hello></hello>foo<p>bar</p></pre>
284-
</div>
283+
<div><pre data-lang="php"><hello></hello>foo<p>bar</p></pre></div>
285284
HTML,
286285
$html,
287286
);

tests/Integration/View/TempestViewRendererTest.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,7 @@ public function test_foreach_consumes_attribute(): void
136136

137137
$this->assertStringContainsStringIgnoringLineEndings(
138138
<<<'HTML'
139-
<title>Home</title>
140-
141-
142-
143-
144-
145-
<table><tbody><tr><td>b</td></tr></tbody></table>
139+
<html lang="en"><head><title>Home</title></head><body><table><tbody><tr><td>a</td></tr><tr><td>b</td></tr></tbody></table></body></html>
146140
HTML,
147141
$html,
148142
);

tests/Integration/View/ViewComponentTest.php

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,17 @@ public function test_view_can_access_dynamic_slots(): void
6969
HTML,
7070
);
7171

72-
$html = $this->render(<<<'HTML'
72+
$html = $this->render(<<<'HTML_WRAP'
7373
<x-test>
7474
<x-slot name="slot-php" language="PHP">PHP Body</x-slot>
7575
<x-slot name="slot-html" language="HTML">HTML Body</x-slot>
7676
</x-test>
77-
HTML);
77+
HTML_WRAP);
7878

79-
$this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML'
79+
$this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML_WRAP'
8080
<div><div>slot-php</div><div>PHP</div><div>PHP</div><div>PHP Body</div></div>
8181
<div><div>slot-html</div><div>HTML</div><div>HTML</div><div>HTML Body</div></div>
82-
HTML, $html);
82+
HTML_WRAP, $html);
8383
}
8484

8585
public function test_dynamic_slots_are_cleaned_up(): void
@@ -155,15 +155,7 @@ public function test_nested_components(): void
155155
{
156156
$this->assertStringEqualsStringIgnoringLineEndings(
157157
expected: <<<'HTML'
158-
<form action="#" method="post"><div><div><label for="a">a</label><input type="number" name="a" id="a" value></input></div>
159-
160-
161-
</div>
162-
<div><label for="b">b</label><input type="text" name="b" id="b" value></input></div>
163-
164-
165-
166-
</form>
158+
<form action="#" method="post"><div><div><label for="a">a</label><input type="number" name="a" id="a" value></input></div></div><div><label for="b">b</label><input type="text" name="b" id="b" value></input></div></form>
167159
HTML,
168160
actual: $this->render(view(
169161
<<<'HTML'
@@ -290,8 +282,7 @@ public function test_with_passed_variable(): void
290282

291283
$this->assertStringEqualsStringIgnoringLineEndings(
292284
<<<HTML
293-
<div>
294-
test </div>
285+
<div>test</div>
295286
HTML,
296287
$rendered,
297288
);
@@ -305,8 +296,7 @@ public function test_with_passed_data(): void
305296

306297
$this->assertStringEqualsStringIgnoringLineEndings(
307298
<<<HTML
308-
<div>
309-
test </div>
299+
<div>test</div>
310300
HTML,
311301
$rendered,
312302
);
@@ -323,8 +313,7 @@ public function test_with_passed_php_data(): void
323313

324314
$this->assertStringEqualsStringIgnoringLineEndings(
325315
<<<HTML
326-
<div>
327-
TEST </div>
316+
<div>TEST</div>
328317
HTML,
329318
$rendered,
330319
);
@@ -464,4 +453,33 @@ public static function view_components(): Generator
464453
'<div foo="fooValue" bar="barValue">body</div>',
465454
];
466455
}
456+
457+
public function test_full_html_document_as_component(): void
458+
{
459+
$this->registerViewComponent('x-layout', <<<'HTML'
460+
<html lang="en">
461+
<head>
462+
<title>Tempest View</title>
463+
</head>
464+
<body>
465+
<x-slot />
466+
</body>
467+
</html>
468+
HTML);
469+
470+
$html = $this->render(<<<'HTML'
471+
<x-layout>
472+
Hello World
473+
</x-layout>
474+
HTML);
475+
476+
$this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML'
477+
<html lang="en"><head><title>Tempest View</title></head><body>
478+
479+
Hello World
480+
481+
482+
</body></html>
483+
HTML, $html);
484+
}
467485
}

tests/Integration/View/ViewTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function test_render(): void
2323
$html = $this->render($view);
2424

2525
$this->assertStringContainsString(
26-
'Hello Brent!',
26+
'Brent!',
2727
$html,
2828
);
2929

0 commit comments

Comments
 (0)