diff --git a/src/LiveComponent/tests/Fixtures/Kernel.php b/src/LiveComponent/tests/Fixtures/Kernel.php index ff8f408cfce..344eb3a8df5 100644 --- a/src/LiveComponent/tests/Fixtures/Kernel.php +++ b/src/LiveComponent/tests/Fixtures/Kernel.php @@ -29,6 +29,7 @@ use Symfony\UX\LiveComponent\Tests\Fixtures\Serializer\MoneyNormalizer; use Symfony\UX\TwigComponent\TwigComponentBundle; use Twig\Environment; +use Twig\Loader\FilesystemLoader; use Zenstruck\Foundry\ZenstruckFoundryBundle; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; @@ -52,6 +53,13 @@ public function renderTemplate(string $template, Environment $twig = null): Resp return new Response($twig->render("{$template}.html.twig")); } + public function renderNamespacedTemplate(string $template, Environment $twig = null): Response + { + $twig ??= $this->container->get('twig'); + + return new Response($twig->render('@'.FilesystemLoader::MAIN_NAMESPACE.'/'.$template.'.html.twig')); + } + public function registerBundles(): iterable { yield new FrameworkBundle(); @@ -142,6 +150,7 @@ protected function configureRoutes(RoutingConfigurator $routes): void ->prefix('/_components'); $routes->add('template', '/render-template/{template}')->controller('kernel::renderTemplate'); + $routes->add('render_namespaced_template', '/render-namespaced-template/{template}')->controller('kernel::renderNamespacedTemplate'); $routes->add('homepage', '/')->controller('kernel::index'); $routes->add('alternate_live_route', '/alt/{_live_component}/{_live_action}')->defaults(['_live_action' => 'get']); } diff --git a/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php b/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php index 4e57d2682e1..d13d7cf9f53 100644 --- a/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php +++ b/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php @@ -259,6 +259,19 @@ public function testItAddsEmbeddedTemplateContextToEmbeddedComponents(): void ; } + public function testItWorksWithNamespacedTemplateNamesForEmbeddedComponents(): void + { + $templateName = 'render_embedded_with_blocks.html.twig'; + $obscuredName = 'fb7992f74bbb43c08e47b7cf5c880edb'; + $this->addTemplateMap($obscuredName, $templateName); + + $this->browser() + ->visit('/render-namespaced-template/render_embedded_with_blocks') + ->assertSuccessful() + ->assertElementAttributeContains('.component2', 'data-live-props-value', '"data-host-template":"'.$obscuredName.'"') + ; + } + public function testItUseBlocksFromEmbeddedContextUsingMultipleComponents(): void { $templateName = 'render_multiple_embedded_with_blocks.html.twig'; diff --git a/src/TwigComponent/src/Twig/ComponentNode.php b/src/TwigComponent/src/Twig/ComponentNode.php index 0fed5216ccf..d5f87e373c0 100644 --- a/src/TwigComponent/src/Twig/ComponentNode.php +++ b/src/TwigComponent/src/Twig/ComponentNode.php @@ -68,7 +68,7 @@ public function compile(Compiler $compiler): void ->raw('), ') ->raw($this->getAttribute('only') ? '[]' : '$context') ->raw(', ') - ->string($this->getAttribute('name')) + ->string($this->parseTemplateName($this->getAttribute('name'))) ->raw(', ') ->raw($this->getAttribute('index')) ->raw(");\n") @@ -91,4 +91,20 @@ public function compile(Compiler $compiler): void ->raw("\n") ; } + + /** + * Copied from Twig\Loader\FilesystemLoader, and adjusted to needs for this class. + */ + private function parseTemplateName(string $name): mixed + { + if (isset($name[0]) && '@' == $name[0]) { + if (false === $pos = strpos($name, '/')) { + throw new \LogicException(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); + } + + return substr($name, $pos + 1); + } + + return $name; + } }