Skip to content

Commit

Permalink
DEBUG outerblocks
Browse files Browse the repository at this point in the history
  • Loading branch information
smnandre committed Nov 10, 2024
1 parent e74c44e commit b3e5211
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 10 deletions.
56 changes: 53 additions & 3 deletions src/TwigComponent/src/BlockStack.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,17 @@ final class BlockStack
* @var array<class-string, int>
*/
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;
Expand All @@ -48,33 +57,74 @@ 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)
// allows us to remember the link between the original name and the new randomized name.
// 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;
Expand All @@ -87,7 +137,7 @@ private function findHostEmbeddedTemplateIndex(): int
}
}
}

return 0;
}

Expand Down
12 changes: 11 additions & 1 deletion src/TwigComponent/src/Twig/ComponentNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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");

/*
Expand Down
6 changes: 5 additions & 1 deletion src/TwigComponent/src/Twig/ComponentTokenParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}
15 changes: 15 additions & 0 deletions ux.symfony.com/templates/components/Foo.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% props a, b = 'b' %}

<div {{ attributes }} style="border: 2px dashed red; margin:1rem;padding:1rem;">

{{ dump(em_index ?? '', em_template ?? '') }}

Before content
{{ dump(a, b, c ?? null) }}
{% block content %}
<div style="border: 2px solid blue">
{{ dump(em_index ?? '', em_template ?? '') }}
</div>
{% endblock %}
After content
</div>
57 changes: 52 additions & 5 deletions ux.symfony.com/templates/support.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,59 @@

{% block content %}

<div class="hero">
<div class="container-fluid container-xxl px-4 pt-4 px-md-5">
<h1 class="text-center mt-5"><a href="{{ url('app_support') }}">Support</a></h1>
<p class="text-center mt-2 mb-5">Ask questions about Symfony UX and find the answers you need.</p>
<div class="container-xl">

{% block bar %}
bar
{% endblock %}

{% set b = 'bb' %}
{% set c = 'CC' %}

{# <h2>No content</h2>#}
{# <twig:Foo a="AA" />#}
{# #}
{# <h2>Content</h2>#}
{# <twig:Foo a="AA">CONTENT</twig:Foo>#}

<h2>OuterBlock</h2>
<twig:Foo a="AA1">
{{ outerBlocks.bar }}
</twig:Foo>

<hr style="margin: 4rem; border: 0; border-top: 2px solid #ddd;">

<h2>Nested</h2>
<twig:Foo a="AA1">
AA1 inner
<twig:Foo a="AA1.1">
AA1.1 innder
</twig:Foo>
{{ outerBlocks.bar }}
</twig:Foo>

<hr style="margin: 4rem; border: 0; border-top: 2px solid #ddd;">

<h2>Nested Twice</h2>
<twig:Foo a="AA2">
{{ dump({'aaa2': [em_index ??'', em_template ??'']}) }}
AA2 inner
<twig:Foo a="AA2.1">
{{ dump({'aaa2.1': [em_index ??'', em_template ??'']}) }}
AA2.1 innder
{{ outerBlocks.bar }}
</twig:Foo>
<twig:Foo a="AA2.2">
{{ dump({'aaa2.2': [em_index ??'', em_template ??'']}) }}
AA2.2 innder
{{ outerBlocks.bar }}
</twig:Foo>
{# {{ outerBlocks.bar }}#}
</twig:Foo>

{{ dump('foo') }}

</div>
</div>

<section style="--padding:0;">
<div class="container-fluid container px-4 pt-4 px-md-5" style="max-width: 1000px;">
Expand Down

0 comments on commit b3e5211

Please sign in to comment.