diff --git a/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php b/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php index ce1b8a18e53..cd10de91364 100644 --- a/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php +++ b/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php @@ -41,7 +41,7 @@ public function process(ContainerBuilder $container): void $tag['service_id'] = $id; $tag['class'] = $definition->getClass(); - $tag['template'] = $tag['template'] ?? "components/{$tag['key']}.html.twig"; + $tag['template'] = $tag['template'] ?? sprintf('components/%s.html.twig', str_replace(':', '/', $tag['key'])); $componentConfig[$tag['key']] = $tag; } } diff --git a/src/TwigComponent/src/Resources/doc/index.rst b/src/TwigComponent/src/Resources/doc/index.rst index e09ca246f2c..e39a1aae933 100644 --- a/src/TwigComponent/src/Resources/doc/index.rst +++ b/src/TwigComponent/src/Resources/doc/index.rst @@ -190,6 +190,13 @@ as the second argument to the ``AsTwigComponent`` attribute: // ... } +Twig Template Namespaces +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can use a ``:`` in your component's name to indicate a namespace. The default +template will replace the ``:`` with ``/``. For example, a component with the name +``form:input`` will look for a template in ``templates/components/form/input.html.twig``. + The mount() Method ~~~~~~~~~~~~~~~~~~ diff --git a/src/TwigComponent/tests/Fixtures/Component/NamespacedComponent.php b/src/TwigComponent/tests/Fixtures/Component/NamespacedComponent.php new file mode 100644 index 00000000000..aea8d4e415d --- /dev/null +++ b/src/TwigComponent/tests/Fixtures/Component/NamespacedComponent.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\UX\TwigComponent\Tests\Fixtures\Component; + +use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; + +#[AsTwigComponent('foo:bar:baz')] +final class NamespacedComponent +{ +} diff --git a/src/TwigComponent/tests/Fixtures/templates/components/foo/bar/baz.html.twig b/src/TwigComponent/tests/Fixtures/templates/components/foo/bar/baz.html.twig new file mode 100644 index 00000000000..1b21043f58d --- /dev/null +++ b/src/TwigComponent/tests/Fixtures/templates/components/foo/bar/baz.html.twig @@ -0,0 +1 @@ +Content... diff --git a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php index 9aab7a12ec9..dd98d5234ef 100644 --- a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php +++ b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php @@ -130,6 +130,13 @@ public function testCanRenderEmbeddedComponent(): void $this->assertStringContainsString('custom td (1)', $output); } + public function testComponentWithNamespace(): void + { + $output = $this->renderComponent('foo:bar:baz'); + + $this->assertStringContainsString('Content...', $output); + } + private function renderComponent(string $name, array $data = []): string { return self::getContainer()->get(Environment::class)->render('render_component.html.twig', [