Deferred support in Twig 3

Signed-off-by: Andy Miller <rhuk@mac.com>
This commit is contained in:
Andy Miller
2025-09-20 18:38:27 -06:00
parent 35f5d2f329
commit cb0bbcdb8b
6 changed files with 599 additions and 375 deletions

View File

@@ -1,4 +1,9 @@
<<<<<<< HEAD
# v1.8.0-beta.5
## mm/dd/2025
1. [](#bugfix)
* Deferred Extension support in Forked version of Twig 3
# v1.8.0-beta.4
## 01/27/2025
@@ -47,7 +52,7 @@
* Removed unsupported **APC**, **WinCache**, **XCache** and **Memcache**, use apcu or memcached instead
* Removed `system.umask_fix` setting for security reasons
* Support phpstan level 6 in Framework classes
=======
# v1.7.49.5
## 09/10/2025

View File

@@ -37,7 +37,7 @@
"symfony/var-dumper": "^6.4",
"symfony/process": "^6.4",
"symfony/http-client": "^6.4",
"twig/twig": "2.x-dev",
"twig/twig": "3.x-dev",
"monolog/monolog": "^2.0",
"doctrine/cache": "^2.2",
"doctrine/collections": "^2.2",
@@ -49,7 +49,7 @@
"rockettheme/toolbox": "v2.x-dev",
"composer/ca-bundle": "^1.5",
"composer/semver": "^3.4",
"dragonmantank/cron-expression": "^3.0",
"dragonmantank/cron-expression": "^3.3",
"willdurand/negotiation": "^3.1",
"rhukster/dom-sanitizer": "^1.0",
"matthiasmullie/minify": "^1.3",

936
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,9 +25,8 @@ class TwigEnvironment extends Environment
/**
* @inheritDoc
*
* TODO: Needed for Twig 1 compatibility.
*/
public function resolveTemplate($names)
public function resolveTemplate($names): TemplateWrapper
{
if (!\is_array($names)) {
$names = [$names];
@@ -52,7 +51,7 @@ class TwigEnvironment extends Environment
}
// Throws LoaderError: Unable to find template "%s".
return $this->loadTemplate($name);
return $this->load($name);
}
throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));

View File

@@ -23,19 +23,30 @@ final class DeferredBlockNode extends BlockNode
$name = $this->getAttribute('name');
$compiler
->write("public function block_$name(\$context, array \$blocks = [])\n", "{\n")
->addDebugInfo($this)
->write("/**\n")
->write(" * @return iterable<null|scalar|\\Stringable>\n")
->write(" */\n")
->write("public function block_$name(array \$context, array \$blocks = []): iterable\n", "{\n")
->indent()
->write("\$macros = \$this->macros;\n")
->write("\$this->deferred->defer(\$this, '$name');\n")
->write("yield from [];\n")
->outdent()
->write("}\n\n")
;
$compiler
->addDebugInfo($this)
->write("public function block_{$name}_deferred(\$context, array \$blocks = [])\n", "{\n")
->write("/**\n")
->write(" * @return iterable<null|scalar|\\Stringable>\n")
->write(" */\n")
->write("public function block_{$name}_deferred(array \$context, array \$blocks = []): iterable\n", "{\n")
->indent()
->write("\$macros = \$this->macros;\n")
->subcompile($this->getNode('body'))
->write("\$this->deferred->resolve(\$this, \$context, \$blocks);\n")
->write("yield from [];\n")
->outdent()
->write("}\n\n")
;

View File

@@ -55,8 +55,9 @@ final class DeferredTokenParser extends AbstractTokenParser
private function replaceBlockNode(string $name) : void
{
$block = $this->parser->getBlock($name)->getNode('0');
$this->parser->setBlock($name, $this->createDeferredBlockNode($block));
$blockContainer = $this->parser->getBlock($name);
$block = $blockContainer->getNode('0');
$blockContainer->setNode('0', $this->createDeferredBlockNode($block));
}
private function createDeferredBlockNode(BlockNode $block) : DeferredBlockNode