From e122fa32a3d968d00e805b575ad0c1f4970d018c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Sat, 22 Feb 2025 13:10:59 +0100 Subject: [PATCH] [TwigComponent] Add compat with Twig 3.21 "load"/"loadTemplate" cf https://github.com/twigphp/Twig/pull/4583/files --- src/TwigComponent/src/ComponentRenderer.php | 14 +++++--- src/TwigComponent/src/Twig/ComponentNode.php | 33 +++++++++++++------ .../Integration/ComponentExtensionTest.php | 2 +- .../Integration/EmbeddedComponentTest.php | 2 +- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/TwigComponent/src/ComponentRenderer.php b/src/TwigComponent/src/ComponentRenderer.php index 2595d646bbd..3a602cf15f0 100644 --- a/src/TwigComponent/src/ComponentRenderer.php +++ b/src/TwigComponent/src/ComponentRenderer.php @@ -17,6 +17,7 @@ use Symfony\UX\TwigComponent\Event\PreCreateForRenderEvent; use Symfony\UX\TwigComponent\Event\PreRenderEvent; use Twig\Environment; +use Twig\Template; /** * @author Kevin Bond @@ -70,11 +71,14 @@ public function render(MountedComponent $mounted): string } try { - return $this->twig->loadTemplate( - $this->templateClasses[$template = $event->getTemplate()] ??= $this->twig->getTemplateClass($template), - $template, - $templateIndex, - )->render($variables); + if (method_exists(Template::class, 'load')) { + return $this->twig->load($event->getTemplate())->render($variables); + } + + // Environment::loadTemplate is deprecated since Twig 3.21 + $templateClass = $this->templateClasses[$template = $event->getTemplate()] ??= $this->twig->getTemplateClass($template, $templateIndex); + + return $this->twig->loadTemplate($templateClass, $template, $templateIndex)->render($variables); } finally { $mounted = $this->componentStack->pop(); diff --git a/src/TwigComponent/src/Twig/ComponentNode.php b/src/TwigComponent/src/Twig/ComponentNode.php index df735079570..1f8a11b6e32 100644 --- a/src/TwigComponent/src/Twig/ComponentNode.php +++ b/src/TwigComponent/src/Twig/ComponentNode.php @@ -19,6 +19,7 @@ use Twig\Node\Expression\AbstractExpression; use Twig\Node\Node; use Twig\Node\NodeOutputInterface; +use Twig\Template; /** * @author Fabien Potencier @@ -154,17 +155,29 @@ public function compile(Compiler $compiler): void if ($useYield) { $compiler->write('yield from '); } - $compiler - ->write('$this->loadTemplate(') - ->string($this->getAttribute('embedded_template')) - ->raw(', ') - ->repr($this->getTemplateName()) - ->raw(', ') - ->repr($this->getTemplateLine()) - ->raw(', ') - ->string($this->getAttribute('embedded_index')) - ->raw(')'); + if (method_exists(Template::class, 'load')) { + $compiler + ->write('$this->load(') + ->string($this->getAttribute('embedded_template')) + ->raw(', ') + ->raw($this->getTemplateLine()) + ->raw(', ') + ->string($this->getAttribute('embedded_index')) + ->raw(')'); + } else { + // Environment::loadTemplate is deprecated since Twig 3.21 + $compiler + ->write('$this->loadTemplate(') + ->string($this->getAttribute('embedded_template')) + ->raw(', ') + ->repr($this->getTemplateName()) + ->raw(', ') + ->repr($this->getTemplateLine()) + ->raw(', ') + ->string($this->getAttribute('embedded_index')) + ->raw(')'); + } if ($useYield) { $compiler->raw('->unwrap()->yield('); } else { diff --git a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php index 591ba30bd99..88de47b7d68 100644 --- a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php +++ b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php @@ -425,7 +425,7 @@ public function testComponentWithPropsFromTemplateAndClass(): void public function testComponentWithConflictBetweenPropsFromTemplateAndClass(): void { $this->expectException(RuntimeError::class); - $this->expectExceptionMessage('Cannot define prop "name" in template "components/Conflict.html.twig". Property already defined in component class "Symfony\UX\TwigComponent\Tests\Fixtures\Component\Conflict".'); + $this->expectExceptionMessage('Cannot define prop "name" in template "components/Conflict.html.twig"'); self::getContainer()->get(Environment::class)->render('component_with_conflict_between_props_from_template_and_class.html.twig'); } diff --git a/src/TwigComponent/tests/Integration/EmbeddedComponentTest.php b/src/TwigComponent/tests/Integration/EmbeddedComponentTest.php index baee7f226e0..4befb9202a6 100644 --- a/src/TwigComponent/tests/Integration/EmbeddedComponentTest.php +++ b/src/TwigComponent/tests/Integration/EmbeddedComponentTest.php @@ -162,7 +162,7 @@ public function testAccessingTheHierarchyTooHighThrowsAnException(): void { // Twig renamed "array" into "sequence" in 3.11 $this->expectExceptionMessage('Key "$this" for '); - $this->expectExceptionMessage('with keys "app, __embedded" does not exist.'); + $this->expectExceptionMessage('with keys "app, __embedded" does not exist'); self::render('embedded_component_hierarchy_exception.html.twig'); }