From b3e521111968e45496439a162aca67056410ab00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Sun, 10 Nov 2024 14:56:47 +0100 Subject: [PATCH] DEBUG outerblocks --- src/TwigComponent/src/BlockStack.php | 56 +++++++++++++++++- src/TwigComponent/src/Twig/ComponentNode.php | 12 +++- .../src/Twig/ComponentTokenParser.php | 6 +- .../templates/components/Foo.html.twig | 15 +++++ ux.symfony.com/templates/support.html.twig | 57 +++++++++++++++++-- 5 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 ux.symfony.com/templates/components/Foo.html.twig diff --git a/src/TwigComponent/src/BlockStack.php b/src/TwigComponent/src/BlockStack.php index 1d4cb90ba7a..7fdb4486a91 100644 --- a/src/TwigComponent/src/BlockStack.php +++ b/src/TwigComponent/src/BlockStack.php @@ -32,8 +32,17 @@ final class BlockStack * @var array */ private static array $templateIndexStack = []; + + private readonly int $templateIndex; + public function __construct( + private readonly string $templateClass, + private readonly array $blocks, + private readonly array $embeddedContext, + ){ + $this->templateIndex = self::getTemplateIndexFromTemplateClassname($this->templateClass); + } - public function convert(array $blocks, int $targetEmbeddedTemplateIndex): array + public function convert(array $blocks, int $targetEmbeddedTemplateIndex, string $embeddedTemplate): array { $newBlocks = []; $hostEmbeddedTemplateIndex = null; @@ -48,10 +57,11 @@ public function convert(array $blocks, int $targetEmbeddedTemplateIndex): array // Each component has its own embedded template. That template's index uniquely // identifies the block definition. $hostEmbeddedTemplateIndex ??= $this->findHostEmbeddedTemplateIndex(); + dump(hostEmbeddedTemplateIndex: $hostEmbeddedTemplateIndex); // Change the name of outer blocks to something unique so blocks of nested components aren't overridden, // which otherwise might cause a recursion loop when nesting components. - $newName = self::OUTER_BLOCK_PREFIX.$blockName.'_'.mt_rand(); + $newName = self::OUTER_BLOCK_PREFIX.$blockName.'_a'.$hostEmbeddedTemplateIndex.'_a'.$targetEmbeddedTemplateIndex; $newBlocks[$newName] = $block; // The host index combined with the index of the embedded template where the block can be used (target) @@ -59,22 +69,62 @@ public function convert(array $blocks, int $targetEmbeddedTemplateIndex): array // That way we can map a call like `block(outerBlocks.block_name)` to the randomized name. $this->stack[$blockName][$targetEmbeddedTemplateIndex][$hostEmbeddedTemplateIndex] = $newName; } + + $trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2); + dump($trace[1]['class'] ?? 'no class'); + + dump( + class: $this->templateClass, + index: $this->templateIndex, + blocks: $this->blocks, + embeddedContext: $this->embeddedContext, + newBlocks: $newBlocks, + hostEmbeddedTemplateIndex: $hostEmbeddedTemplateIndex, + targetEmbeddedTemplateIndex: $targetEmbeddedTemplateIndex, + targetEmbeddedTemplate: $embeddedTemplate, + ); return $newBlocks; } public function __call(string $name, array $arguments) { + dump(sprintf('call block %s ', $name)); + dump($this->stack[$name]); + + $trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2); + dump($trace[1]['class'] ?? 'no class'); + + dump($this->templateClass, $this->templateIndex); + dump($name, $arguments); + + $trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2); + if (null === $classname = $trace[1]['class'] ?? null) { + throw new \LogicException('Unable to guess the block name.'); + } + $callingEmbeddedTemplateIndex = $this->findCallingEmbeddedTemplateIndex(); $hostEmbeddedTemplateIndex = $this->findHostEmbeddedTemplateIndexFromCaller(); + + dump($callingEmbeddedTemplateIndex, $hostEmbeddedTemplateIndex); + dump($this->stack[$name][$callingEmbeddedTemplateIndex] ?? []); return $this->stack[$name][$callingEmbeddedTemplateIndex][$hostEmbeddedTemplateIndex] ?? self::OUTER_BLOCK_FALLBACK_NAME; } private function findHostEmbeddedTemplateIndex(): int { + // $trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2); + // if (isset($trace[1]['class']) && $trace[1]['class'] instanceof Template) { + // $classname = $trace[1]['class']::class; + // return self::getTemplateIndexFromTemplateClassname($classname); + // } + // + // return 0; + // $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT); + foreach ($backtrace as $trace) { if (isset($trace['object']) && $trace['object'] instanceof Template) { $classname = $trace['object']::class; @@ -87,7 +137,7 @@ private function findHostEmbeddedTemplateIndex(): int } } } - + return 0; } diff --git a/src/TwigComponent/src/Twig/ComponentNode.php b/src/TwigComponent/src/Twig/ComponentNode.php index 439175c5bfa..6fd62fbba32 100644 --- a/src/TwigComponent/src/Twig/ComponentNode.php +++ b/src/TwigComponent/src/Twig/ComponentNode.php @@ -94,6 +94,9 @@ public function compile(Compiler $compiler): void ->write('} else {') ->raw("\n") ->indent(); + + // $context = $runtime->startEmbedComponent(); + // $context['__parent__'] = $preRenderEvent->getTemplate(); /* * Block 2) Create the component & return render info @@ -139,11 +142,18 @@ public function compile(Compiler $compiler): void * Then add them to the block stack and get the converted embedded blocks. */ $compiler - ->write(\sprintf('$embeddedContext["outerBlocks"] ??= new \%s();', BlockStack::class)) + ->write(\sprintf('$embeddedContext["outerBlocks"] ??= new \%s(__CLASS__, $this->blocks, $embeddedContext);', BlockStack::class)) ->raw("\n"); + + $compiler + ->write(sprintf('$embeddedContext["em_template"] = "%s";', $this->getAttribute('embedded_template'))) + ->write(sprintf('$embeddedContext["em_index"] = %s;', $this->getAttribute('embedded_index'))) + ; $compiler->write('$embeddedBlocks = $embeddedContext["outerBlocks"]->convert($blocks, ') ->raw($this->getAttribute('embedded_index')) + ->raw(", ") + ->string($this->getAttribute('embedded_template')) ->raw(");\n"); /* diff --git a/src/TwigComponent/src/Twig/ComponentTokenParser.php b/src/TwigComponent/src/Twig/ComponentTokenParser.php index 3f94c09d627..51d58864c33 100644 --- a/src/TwigComponent/src/Twig/ComponentTokenParser.php +++ b/src/TwigComponent/src/Twig/ComponentTokenParser.php @@ -117,7 +117,11 @@ private function generateEmbeddedTemplateIndex(string $file, int $line): int if (!isset($this->lineAndFileCounts[$fileAndLine])) { $this->lineAndFileCounts[$fileAndLine] = 0; } + + $prefixedTime = str_pad($this->lineAndFileCounts[$fileAndLine], 4, '0', STR_PAD_LEFT); + + return $line.$prefixedTime; - return crc32($fileAndLine).++$this->lineAndFileCounts[$fileAndLine]; + // return crc32($fileAndLine).++$this->lineAndFileCounts[$fileAndLine]; } } diff --git a/ux.symfony.com/templates/components/Foo.html.twig b/ux.symfony.com/templates/components/Foo.html.twig new file mode 100644 index 00000000000..440e37eb77a --- /dev/null +++ b/ux.symfony.com/templates/components/Foo.html.twig @@ -0,0 +1,15 @@ +{% props a, b = 'b' %} + +
+ + {{ dump(em_index ?? '', em_template ?? '') }} + + Before content + {{ dump(a, b, c ?? null) }} + {% block content %} +
+ {{ dump(em_index ?? '', em_template ?? '') }} +
+ {% endblock %} + After content +
diff --git a/ux.symfony.com/templates/support.html.twig b/ux.symfony.com/templates/support.html.twig index 46cbf4108f1..8395e41b089 100644 --- a/ux.symfony.com/templates/support.html.twig +++ b/ux.symfony.com/templates/support.html.twig @@ -8,12 +8,59 @@ {% block content %} -
-
-

Support

-

Ask questions about Symfony UX and find the answers you need.

+
+ + {% block bar %} + bar + {% endblock %} + + {% set b = 'bb' %} + {% set c = 'CC' %} + +{#

No content

#} +{# #} +{# #} +{#

Content

#} +{# CONTENT#} + +

OuterBlock

+ + {{ outerBlocks.bar }} + + +
+ +

Nested

+ + AA1 inner + + AA1.1 innder + + {{ outerBlocks.bar }} + + +
+ +

Nested Twice

+ + {{ dump({'aaa2': [em_index ??'', em_template ??'']}) }} + AA2 inner + + {{ dump({'aaa2.1': [em_index ??'', em_template ??'']}) }} + AA2.1 innder + {{ outerBlocks.bar }} + + + {{ dump({'aaa2.2': [em_index ??'', em_template ??'']}) }} + AA2.2 innder + {{ outerBlocks.bar }} + +{# {{ outerBlocks.bar }}#} + + + {{ dump('foo') }} +
-