Skip to content

Commit 2ca9430

Browse files
committed
[TwigComponent] Fixing bug where traditional blocks aren't handled correctly
1 parent c6e3560 commit 2ca9430

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

src/TwigComponent/src/Twig/TwigPreLexer.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ public function preLexComponents(string $input, bool $insideOfBlock = false): st
5252
}
5353
}
5454

55-
if ($this->consume('<twig:')) {
56-
$componentName = $this->consumeComponentName();
55+
$isTwigHtmlOpening = $this->consume('<twig:');
56+
$isTraditionalBlockOpening = false;
57+
if ($isTwigHtmlOpening || (0 !== \count($this->currentComponents) && $isTraditionalBlockOpening = $this->consume('{% block'))) {
58+
$componentName = $isTraditionalBlockOpening ? 'block' : $this->consumeComponentName();
5759

5860
if ('block' === $componentName) {
5961
// if we're already inside the "default" block, let's close it
@@ -63,6 +65,15 @@ public function preLexComponents(string $input, bool $insideOfBlock = false): st
6365
$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = false;
6466
}
6567

68+
if ($isTraditionalBlockOpening) {
69+
// add what we've consumed so far
70+
$output .= '{% block';
71+
$output .= $this->consumeUntil('%}');
72+
$output .= $this->consumeUntilEndBlock();
73+
74+
continue;
75+
}
76+
6677
$output .= $this->consumeBlock($componentName);
6778

6879
continue;
@@ -119,7 +130,7 @@ public function preLexComponents(string $input, bool $insideOfBlock = false): st
119130
continue;
120131
}
121132

122-
$char = $this->consumeChar();
133+
$char = $this->input[$this->position];
123134
if ("\n" === $char) {
124135
++$this->line;
125136
}
@@ -128,11 +139,13 @@ public function preLexComponents(string $input, bool $insideOfBlock = false): st
128139
if (!empty($this->currentComponents)
129140
&& !$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock']
130141
&& preg_match('/\S/', $char)
142+
&& !$this->check('{% block')
131143
) {
132144
$output .= $this->addDefaultBlock();
133145
}
134146

135147
$output .= $char;
148+
$this->consumeChar();
136149
}
137150

138151
if (!empty($this->currentComponents)) {
@@ -374,10 +387,24 @@ private function consumeUntilEndBlock(): string
374387
}
375388
}
376389

390+
if ('{% endblock %}' === substr($this->input, $this->position, 14)) {
391+
if (1 === $depth) {
392+
// in this case, we want to advanced ALL the way beyond the endblock
393+
$this->position += 14;
394+
break;
395+
} else {
396+
--$depth;
397+
}
398+
}
399+
377400
if ('<twig:block' === substr($this->input, $this->position, 11)) {
378401
++$depth;
379402
}
380403

404+
if ('{% block' === substr($this->input, $this->position, 8)) {
405+
++$depth;
406+
}
407+
381408
if ("\n" === $this->input[$this->position]) {
382409
++$this->line;
383410
}

src/TwigComponent/tests/Unit/TwigPreLexerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ public function getLexTests(): iterable
5252
'{% component \'foo\' %}{% block foo_block %}Foo{% endblock %}{% endcomponent %}',
5353
];
5454

55+
yield 'component_with_traditional_block' => [
56+
'<twig:foo>{% block foo_block %}Foo{% endblock %}</twig:foo>',
57+
'{% component \'foo\' %}{% block foo_block %}Foo{% endblock %}{% endcomponent %}',
58+
];
59+
60+
yield 'traditional_blocks_around_component_do_not_confuse' => [
61+
'Hello {% block foo_block %}Foo{% endblock %}<twig:foo />{% block bar_block %}Bar{% endblock %}',
62+
'Hello {% block foo_block %}Foo{% endblock %}{{ component(\'foo\') }}{% block bar_block %}Bar{% endblock %}',
63+
];
64+
5565
yield 'component_with_embedded_component_inside_block' => [
5666
'<twig:foo><twig:block name="foo_block"><twig:bar /></twig:block></twig:foo>',
5767
'{% component \'foo\' %}{% block foo_block %}{{ component(\'bar\') }}{% endblock %}{% endcomponent %}',

0 commit comments

Comments
 (0)