Skip to content

Commit 102c5f4

Browse files
author
matheo
committed
adding support for the default block
1 parent bd4a214 commit 102c5f4

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/TwigComponent/src/Twig/TwigPreLexer.php

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class TwigPreLexer
2020
private int $length;
2121
private int $position = 0;
2222
private int $line;
23-
/** @var string[] */
23+
// each item has a "name" string key and a "hasDefaultBlock" bool key
24+
/** @var array<string: name, bool: hasDefaultBlock> */
2425
private array $currentComponents = [];
2526

2627
public function __construct(int $startingLine = 1)
@@ -39,6 +40,13 @@ public function preLexComponents(string $input): string
3940
$componentName = $this->consumeComponentName();
4041

4142
if ('block' === $componentName) {
43+
// if we're already inside the "default" block, let's close it
44+
if (!empty($this->currentComponents) && $this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock']) {
45+
$output .= '{% endblock %}';
46+
47+
$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = false;
48+
}
49+
4250
$output .= $this->consumeBlock();
4351

4452
continue;
@@ -48,7 +56,7 @@ public function preLexComponents(string $input): string
4856
$isSelfClosing = $this->consume('/>');
4957
if (!$isSelfClosing) {
5058
$this->consume('>');
51-
$this->currentComponents[] = $componentName;
59+
$this->currentComponents[] = ['name' => $componentName, 'hasDefaultBlock' => false];
5260
}
5361

5462
$output .= "{% component {$componentName}".($attributes ? " with { {$attributes} }" : '').' %}';
@@ -65,9 +73,16 @@ public function preLexComponents(string $input): string
6573
$this->consume('>');
6674

6775
$lastComponent = array_pop($this->currentComponents);
76+
$lastComponentName = $lastComponent['name'];
6877

69-
if ($closingComponentName !== $lastComponent) {
70-
throw new \RuntimeException("Expected closing tag '</t:{$lastComponent}>' but found '</t:{$closingComponentName}>' at line {$this->line}");
78+
if ($closingComponentName !== $lastComponentName) {
79+
throw new \RuntimeException("Expected closing tag '</t:{$lastComponentName}>' but found '</t:{$closingComponentName}>' at line {$this->line}");
80+
}
81+
82+
// we've reached the end of this component. If we're inside the
83+
// default block, let's close it
84+
if ($lastComponent['hasDefaultBlock']) {
85+
$output .= '{% endblock %}';
7186
}
7287

7388
$output .= '{% endcomponent %}';
@@ -79,9 +94,24 @@ public function preLexComponents(string $input): string
7994
if ("\n" === $char) {
8095
++$this->line;
8196
}
97+
98+
// handle adding a default block if needed
99+
if (!empty($this->currentComponents)
100+
&& !$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock']
101+
&& preg_match('/\S/', $char)
102+
) {
103+
$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = true;
104+
$output .= '{% block default %}';
105+
}
106+
82107
$output .= $char;
83108
}
84109

110+
if (!empty($this->currentComponents)) {
111+
$lastComponent = array_pop($this->currentComponents)['name'];
112+
throw new \RuntimeException(sprintf('Expected closing tag "</t:%s>" not found at line %d.', $lastComponent, $this->line));
113+
}
114+
85115
return $output;
86116
}
87117

src/TwigComponent/tests/Unit/TwigPreLexerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,15 @@ public function getLexTests(): iterable
6161
'<t:foo bar />',
6262
'{% component foo with { bar: true } %}{% endcomponent %}',
6363
];
64+
65+
yield 'component_with_default_block_content' => [
66+
'<t:foo>Foo</t:foo>',
67+
'{% component foo %}{% block default %}Foo{% endblock %}{% endcomponent %}',
68+
];
69+
70+
yield 'component_with_default_block_that_holds_a_component_and_multi_blocks' => [
71+
'<t:foo>Foo <t:bar /><t:block name="other_block">Other block</t:block></t:foo>',
72+
'{% component foo %}{% block default %}Foo {% component bar %}{% endcomponent %}{% endblock %}{% block other_block %}Other block{% endblock %}{% endcomponent %}',
73+
];
6474
}
6575
}

0 commit comments

Comments
 (0)