Skip to content

Commit

Permalink
BlockMacros: fixed variables visibility between blocks depend on bloc…
Browse files Browse the repository at this point in the history
…k order, alternative solution [Closes #178]"
  • Loading branch information
dg committed Nov 22, 2020
1 parent 69ac133 commit c2d5557
Show file tree
Hide file tree
Showing 22 changed files with 78 additions and 39 deletions.
6 changes: 3 additions & 3 deletions src/Latte/Compiler/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class Compiler
CONTEXT_XML_COMMENT = self::CONTEXT_HTML_COMMENT,
CONTEXT_XML_BOGUS_COMMENT = self::CONTEXT_HTML_BOGUS_COMMENT;

/** @var string[] @internal */
public $placeholders = [];

/** @var Token[] */
private $tokens;

Expand All @@ -71,9 +74,6 @@ class Compiler
/** @var MacroNode|null */
private $macroNode;

/** @var string[] */
private $placeholders = [];

/** @var string */
private $contentType = self::CONTENT_HTML;

Expand Down
39 changes: 25 additions & 14 deletions src/Latte/Macros/BlockMacros.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class BlockMacros extends MacroSet
/** @var string[] */
private $imports;

/** @var array[] */
private $placeholders;


public static function install(Latte\Compiler $compiler): void
{
Expand Down Expand Up @@ -69,6 +72,7 @@ public function initialize()
$this->index = Template::LAYER_TOP;
$this->extends = null;
$this->imports = [];
$this->placeholders = [];
}


Expand All @@ -78,6 +82,13 @@ public function initialize()
public function finalize()
{
$compiler = $this->getCompiler();
foreach ($this->placeholders as $key => [$index, $blockName]) {
$block = $this->blocks[$index][$blockName] ?? $this->blocks[Template::LAYER_LOCAL][$blockName] ?? null;
$compiler->placeholders[$key] = $block
? 'get_defined_vars()'
: '[]';
}

$meta = [];
foreach ($this->blocks as $layer => $blocks) {
foreach ($blocks as $name => $block) {
Expand Down Expand Up @@ -151,17 +162,19 @@ public function macroInclude(MacroNode $node, PhpWriter $writer)
$name = $item->data->name;
}


$phpName = $this->isDynamic($name)
? $writer->formatWord($name)
: PhpHelpers::dump($name);
if ($this->isDynamic($name)) {
$phpName = $writer->formatWord($name);
$context = '[]';
} else {
$phpName = PhpHelpers::dump($name);
$context = uniqid() . '$iterator'; // for CoreMacros::macroEndForeach
$this->placeholders[$context] = [$this->index, $name];
}

return $writer->write(
'$this->renderBlock' . ($parent ? 'Parent' : '')
. '($__nm = ' . $phpName . ', %node.array? + '
. (isset($this->blocks[$this->index][$name]) || isset($this->blocks[Template::LAYER_LOCAL][$name])
? 'get_defined_vars()'
: '$this->params')
. '($__nm = ' . $phpName . ', '
. '%node.array? + ' . $context
. ($node->modifiers
? ', function ($s, $type) { $__fi = new LR\FilterInfo($type); return %modifyContent($s); }'
: ($noEscape || $parent ? '' : ', ' . PhpHelpers::dump(implode($node->context))))
Expand Down Expand Up @@ -423,12 +436,12 @@ public function macroSnippet(MacroNode $node, PhpWriter $writer): string
"<?php echo ' {$this->snippetAttribute}=\"' . htmlspecialchars(\$this->global->snippetDriver->getHtmlId(%var)) . '\"' ?>",
$data->name
);
return $writer->write('$this->renderBlock(%var, $this->params, null, %var)', $data->name, Template::LAYER_SNIPPET);
return $writer->write('$this->renderBlock(%var, [], null, %var)', $data->name, Template::LAYER_SNIPPET);
}

return $writer->write(
"?>\n<div {$this->snippetAttribute}=\"<?php echo htmlspecialchars(\$this->global->snippetDriver->getHtmlId(%var)) ?>\">"
. '<?php $this->renderBlock(%var, $this->params, null, %var) ?>'
. '<?php $this->renderBlock(%var, [], null, %var) ?>'
. "\n</div><?php ",
$data->name,
$data->name,
Expand Down Expand Up @@ -489,7 +502,7 @@ public function macroSnippetArea(MacroNode $node, PhpWriter $writer): string
);
$this->extractMethod($node, $block);
};
return $writer->write('$this->renderBlock(%var, $this->params, null, %var)', $data->name, Template::LAYER_SNIPPET);
return $writer->write('$this->renderBlock(%var, [], null, %var)', $data->name, Template::LAYER_SNIPPET);
}


Expand Down Expand Up @@ -526,9 +539,7 @@ private function addBlock(MacroNode $node, string $layer = null): Block
private function extractMethod(MacroNode $node, Block $block, string $args = null): void
{
if (preg_match('#\$|n:#', $node->content)) {
$node->content = '<?php '
. ($args === null ? 'extract($__args);' : 'extract($this->params); ' . $args)
. ' ?>' . $node->content;
$node->content = '<?php extract($this->params);' . ($args ?? 'extract($__args);') . '?>' . $node->content;
}
$block->code = preg_replace('#^\n+|(?<=\n)[ \t]+$#D', '', $node->content);
$node->content = substr_replace($node->content, $node->openingCode . "\n", strspn($node->content, "\n"), strlen($block->code));
Expand Down
1 change: 1 addition & 0 deletions tests/Latte/expected/BlockMacros.define.args1.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ d) ';

public function blockOuter(array $__args): void
{
extract($this->params);
extract($__args);
$this->renderBlock($__nm = 'test', ['hello'] + get_defined_vars(), 'html');

Expand Down
1 change: 1 addition & 0 deletions tests/Latte/expected/BlockMacros.define.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockTest(array $__args): void
{
extract($this->params);
extract($__args);
echo ' This is definition #';
echo LR\Filters::escapeHtmlText($var) /* line 4 */;
Expand Down
5 changes: 3 additions & 2 deletions tests/Latte/expected/BlockMacros.dynamicblock.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ final class Template%a% extends Latte\Runtime\Template
}
$iterator = $__it = $__it->getParent();
echo "\n";
$this->renderBlock($__nm = 'dynamic', ['var' => 20] + $this->params, 'html');
$this->renderBlock($__nm = 'dynamic', ['var' => 20] + [], 'html');
echo "\n";
$this->renderBlock($__nm = 'static', ['var' => 30] + get_defined_vars(), 'html');
echo "\n";
$this->renderBlock($__nm = ($name . ''), ['var' => 40] + $this->params, 'html');
$this->renderBlock($__nm = ($name . ''), ['var' => 40] + [], 'html');
echo "\n";
$this->addBlock($__nm = "word$name", 'html', [[$this, 'blockWord_name']], null);
$this->renderBlock($__nm, get_defined_vars());
Expand Down Expand Up @@ -101,6 +101,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockStatic(array $__args): void
{
extract($this->params);
extract($__args);
echo ' Static block #';
echo LR\Filters::escapeHtmlText($var) /* line 4 */;
Expand Down
1 change: 1 addition & 0 deletions tests/Latte/expected/BlockMacros.embed.file.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockA(array $__args): void
{
extract($this->params);
extract($__args);
echo ' ';
$this->initBlockLayer(2);
Expand Down
2 changes: 1 addition & 1 deletion tests/Latte/expected/BlockMacros.import.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ final class Template%a% extends Latte\Runtime\Template
public function main(): array
{
%A%
$this->renderBlock($__nm = 'test', $this->params, 'html');
$this->renderBlock($__nm = 'test', [], 'html');
echo ' ';
%A%
}
Expand Down
1 change: 1 addition & 0 deletions tests/Latte/expected/BlockMacros.includeblock.inc.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockTest(array $__args): void
{
extract($this->params);
extract($__args);
echo ' Parent: ';
echo LR\Filters::escapeHtmlText(basename($this->getReferringTemplate()->getName())) /* line 3 */;
Expand Down
2 changes: 1 addition & 1 deletion tests/Latte/expected/BlockMacros.includeblock.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ final class Template%a% extends Latte\Runtime\Template
$this->createTemplate("inc", get_defined_vars(), "includeblock")->renderToContentType('html');
echo rtrim(ob_get_clean());
echo "\n";
$this->renderBlock($__nm = 'test', $this->params, 'html');
$this->renderBlock($__nm = 'test', [], 'html');
%A%
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ final class Template%a% extends Latte\Runtime\Template
<div id="content">
';
$this->renderBlock($__nm = 'content', $this->params, 'html');
$this->renderBlock($__nm = 'content', [], 'html');
echo "\n";
$this->renderBlock($__nm = 'content', $this->params, function ($s, $type) {
$this->renderBlock($__nm = 'content', [], function ($s, $type) {
$__fi = new LR\FilterInfo($type);
return LR\Filters::convertTo($__fi, 'html', $this->filters->filterContent('upper', $__fi, $this->filters->filterContent('striphtml', $__fi, $s)));
});
Expand Down
2 changes: 2 additions & 0 deletions tests/Latte/expected/BlockMacros.inheritance.child1.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockTitle(array $__args): void
{
extract($this->params);
extract($__args);
echo 'Homepage | ';
$this->renderBlockParent($__nm = 'title', get_defined_vars());
Expand All @@ -51,6 +52,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockContent(array $__args): void
{
extract($this->params);
extract($__args);
echo ' <ul>
';
Expand Down
1 change: 1 addition & 0 deletions tests/Latte/expected/BlockMacros.inheritance.child2.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockContent(array $__args): void
{
extract($this->params);
extract($__args);
echo ' <h1>';
$this->renderBlock('title', get_defined_vars());
Expand Down
5 changes: 3 additions & 2 deletions tests/Latte/expected/BlockMacros.local.dynamic.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ final class Template%a% extends Latte\Runtime\Template
}
$iterator = $__it = $__it->getParent();
echo "\n";
$this->renderBlock($__nm = 'dynamic', ['var' => 20] + $this->params, 'html');
$this->renderBlock($__nm = 'dynamic', ['var' => 20] + [], 'html');
echo "\n";
$this->renderBlock($__nm = 'static', ['var' => 30] + get_defined_vars(), 'html');
echo "\n";
$this->renderBlock($__nm = ($name . ''), ['var' => 40] + $this->params, 'html');
$this->renderBlock($__nm = ($name . ''), ['var' => 40] + [], 'html');
echo "\n";
$this->addBlock($__nm = "word$name", 'html', [[$this, 'blockWord_name']], 'local');
$this->renderBlock($__nm, get_defined_vars());
Expand Down Expand Up @@ -90,6 +90,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockStatic(array $__args): void
{
extract($this->params);
extract($__args);
echo ' Static block #';
echo LR\Filters::escapeHtmlText($var) /* line 4 */;
Expand Down
8 changes: 6 additions & 2 deletions tests/Latte/expected/BlockMacros.snippet.block.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,21 @@ final class Template%a% extends Latte\Runtime\Template
<div id="';
echo htmlspecialchars($this->global->snippetDriver->getHtmlId('outer'));
echo '">';
$this->renderBlock('outer', $this->params, null, 'snippet');
$this->renderBlock('outer', [], null, 'snippet');
echo '</div>';
%A%
}


public function blockBlock1(array $__args): void
{
extract($this->params);
extract($__args);
echo '<div';
echo ' id="' . htmlspecialchars($this->global->snippetDriver->getHtmlId('snippet')) . '"';
echo '>
';
$this->renderBlock('snippet', $this->params, null, 'snippet');
$this->renderBlock('snippet', [], null, 'snippet');
echo '</div>
';

Expand All @@ -40,6 +41,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockBlock2(array $__args): void
{
extract($this->params);
extract($__args);
echo '<div';
echo ' id="' . htmlspecialchars($this->global->snippetDriver->getHtmlId($__nm = "inner-$id")) . '"';
Expand All @@ -61,6 +63,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockSnippet(array $__args): void
{
extract($this->params);
extract($__args);
$this->global->snippetDriver->enter("snippet", 'static');
try {
Expand All @@ -76,6 +79,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockOuter(array $__args): void
{
extract($this->params);
extract($__args);
$this->global->snippetDriver->enter("outer", 'static');
try {
Expand Down
6 changes: 4 additions & 2 deletions tests/Latte/expected/BlockMacros.snippet.dynamic.alt.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ final class Template%a% extends Latte\Runtime\Template
echo '<div id="';
echo htmlspecialchars($this->global->snippetDriver->getHtmlId('outer1'));
echo '">';
$this->renderBlock('outer1', $this->params, null, 'snippet');
$this->renderBlock('outer1', [], null, 'snippet');
echo '</div>
<div id="';
echo htmlspecialchars($this->global->snippetDriver->getHtmlId('outer2'));
echo '">';
$this->renderBlock('outer2', $this->params, null, 'snippet');
$this->renderBlock('outer2', [], null, 'snippet');
echo '</div>';
%A%
}
Expand All @@ -34,6 +34,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockOuter1(array $__args): void
{
extract($this->params);
extract($__args);
$this->global->snippetDriver->enter("outer1", 'static');
try {
Expand Down Expand Up @@ -66,6 +67,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockOuter2(array $__args): void
{
extract($this->params);
extract($__args);
$this->global->snippetDriver->enter("outer2", 'static');
try {
Expand Down
3 changes: 2 additions & 1 deletion tests/Latte/expected/BlockMacros.snippet.dynamic.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ final class Template%a% extends Latte\Runtime\Template
echo '<div id="';
echo htmlspecialchars($this->global->snippetDriver->getHtmlId('outer'));
echo '">';
$this->renderBlock('outer', $this->params, null, 'snippet');
$this->renderBlock('outer', [], null, 'snippet');
echo '</div>';
%A%
}
Expand All @@ -28,6 +28,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockOuter(array $__args): void
{
extract($this->params);
extract($__args);
$this->global->snippetDriver->enter("outer", 'static');
try {
Expand Down
3 changes: 2 additions & 1 deletion tests/Latte/expected/BlockMacros.snippet.dynamic2.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ final class Template%a% extends Latte\Runtime\Template
echo '<div id="';
echo htmlspecialchars($this->global->snippetDriver->getHtmlId('outer'));
echo '">';
$this->renderBlock('outer', $this->params, null, 'snippet');
$this->renderBlock('outer', [], null, 'snippet');
echo '</div>';
%A%
}
Expand All @@ -28,6 +28,7 @@ final class Template%a% extends Latte\Runtime\Template

public function blockOuter(array $__args): void
{
extract($this->params);
extract($__args);
$this->global->snippetDriver->enter("outer", 'static');
try {
Expand Down
Loading

0 comments on commit c2d5557

Please sign in to comment.