diff --git a/src/TwigComponent/tests/Fixtures/Component/FooBar/Baz.php b/src/TwigComponent/tests/Fixtures/Component/FooBar/Baz.php new file mode 100644 index 00000000000..9efa0081ddb --- /dev/null +++ b/src/TwigComponent/tests/Fixtures/Component/FooBar/Baz.php @@ -0,0 +1,22 @@ + + * + * 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\FooBar; + +use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; + +/** + * @author Simon André + */ +#[AsTwigComponent('FooBar:Baz')] +final class Baz +{ +} diff --git a/src/TwigComponent/tests/Fixtures/EventListener/FooBarComponentTemplateListener.php b/src/TwigComponent/tests/Fixtures/EventListener/FooBarComponentTemplateListener.php new file mode 100644 index 00000000000..f58f8655b67 --- /dev/null +++ b/src/TwigComponent/tests/Fixtures/EventListener/FooBarComponentTemplateListener.php @@ -0,0 +1,43 @@ + + * + * 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\EventListener; + +use Symfony\Component\EventDispatcher\Attribute\AsEventListener; +use Symfony\UX\TwigComponent\Event\PreRenderEvent; + +/** + * Change the template of "FooBarBaz:" components during PrePrenderEvent. + * Before: + * FooBar:Baz -> FooBar/Baz.html.twig + * After: + * FooBar:Baz -> FooBar/Baz.foo_bar.html.twig + * + * @see PreRenderEvent + */ +class FooBarComponentTemplateListener +{ + #[AsEventListener] + public function onPreRender(PreRenderEvent $event): void + { + $metadata = $event->getMetadata(); + if (!str_starts_with($metadata->getName(), 'FooBar:')) { + return; + } + + if (!str_ends_with($event->getTemplate(), '.html.twig')) { + return; + } + + $template = substr($event->getTemplate(), 0, -strlen('.html.twig')).'.foo_bar.html.twig'; + $event->setTemplate($template); + } +} diff --git a/src/TwigComponent/tests/Integration/ComponentEventTest.php b/src/TwigComponent/tests/Integration/ComponentEventTest.php new file mode 100644 index 00000000000..fac7458447d --- /dev/null +++ b/src/TwigComponent/tests/Integration/ComponentEventTest.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\UX\TwigComponent\Tests\Integration; + +use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Twig\Environment; +use Twig\Loader\ArrayLoader; + +/** + * The template can be updated by PreRender event listeners. + * + * @author Simon André + */ +final class ComponentEventTest extends KernelTestCase +{ + /** + * @dataProvider provideFooBarSyntaxes + */ + public function testTemplateIsUpdatedByEventListener(string $syntax): void + { + /** @var Environment $environment */ + $environment = self::getContainer()->get(Environment::class); + $environment->setLoader(new ArrayLoader([ + 'components/FooBar/Baz.foo_bar.html.twig' => 'updated', + 'components/FooBar/Baz.html.twig' => 'original', + ])); + + $component = $environment->createTemplate($syntax); + $result = $component->render(); + + self::assertSame('updated', $result); + } + + public static function provideFooBarSyntaxes(): iterable + { + yield 'TWIG component tag' => ['{% component "FooBar:Baz" %}{% endcomponent %}']; + yield 'TWIG component function' => ['{{ component("FooBar:Baz") }}']; + yield 'HTML self-closing tag' => ['']; + yield 'HTML open-close tag' => ['']; + } +}