diff --git a/src/Node/ComponentNode.php b/src/Node/ComponentNode.php index 06167cf..3fe56ca 100644 --- a/src/Node/ComponentNode.php +++ b/src/Node/ComponentNode.php @@ -5,6 +5,7 @@ use Performing\TwigComponents\Configuration; use Performing\TwigComponents\View\ComponentAttributeBag; use Performing\TwigComponents\View\ComponentSlot; +use Twig\Attribute\YieldReady; use Twig\Compiler; use Twig\Node\Expression\AbstractExpression; use Twig\Node\Expression\ConstantExpression; @@ -12,6 +13,7 @@ use Twig\Node\IncludeNode; use Twig\Node\Node; +#[YieldReady] final class ComponentNode extends IncludeNode { private Configuration $configuration; @@ -40,16 +42,17 @@ public function compile(Compiler $compiler): void ->write('$slotsStack = $slotsStack ?? [];' . PHP_EOL) ->write('$slotsStack[] = $slots ?? [];' . PHP_EOL) ->write('$slots = [];' . PHP_EOL) - ->write("ob_start();" . PHP_EOL) + ->write('$slot = implode("", iterator_to_array((function () use (&$slots, &$context) {' . PHP_EOL) ->subcompile($this->getNode('slot')) - ->write('$slot = ob_get_clean();' . PHP_EOL) - ->write(sprintf('$%s->display(', $template)); + ->write("})() ?? new \EmptyIterator()));" . PHP_EOL) + ->write(sprintf('yield from $%s->unwrap()->yield(', $template)); $this->addTemplateArguments($compiler); $compiler ->raw(");\n") ->write('$slots = array_pop($slotsStack);' . PHP_EOL) + ->write("yield '';") ->write("}\n"); } diff --git a/src/Node/SlotNode.php b/src/Node/SlotNode.php index e90b903..bbd3df7 100644 --- a/src/Node/SlotNode.php +++ b/src/Node/SlotNode.php @@ -3,12 +3,14 @@ namespace Performing\TwigComponents\Node; use Performing\TwigComponents\View\ComponentSlot; +use Twig\Attribute\YieldReady; use Twig\Compiler; use Twig\Node\Expression\AbstractExpression; use Twig\Node\Node; use Twig\Node\NodeOutputInterface; +#[YieldReady] final class SlotNode extends Node implements NodeOutputInterface { public function __construct($name, $body, ?AbstractExpression $variables, int $lineno = 0) @@ -25,9 +27,10 @@ public function compile(Compiler $compiler): void $name = $this->getAttribute('name'); $compiler - ->write('ob_start();') + ->write('$body = (function () use (&$slots, &$context) {') ->subcompile($this->getNode('body')) - ->write('$body = ob_get_clean();' . PHP_EOL) + ->write('})() ?? new \EmptyIterator();' . PHP_EOL) + ->write('$body = implode("", iterator_to_array($body));' . PHP_EOL) ->write("\$slots['$name'] = new " . ComponentSlot::class . "(\$body, "); if ($this->hasNode('variables')) {