-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[TwigBundle] Enable #[AsTwigFilter]
, #[AsTwigFunction]
and #[AsTwigTest]
attributes to configure runtime extensions
#52748
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
Outdated
Show resolved
Hide resolved
1dc34e4
to
edbf868
Compare
src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/RuntimeLoaderPass.php
Outdated
Show resolved
Hide resolved
97a93fe
to
a8762ac
Compare
src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/RuntimeLoaderPass.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/RuntimeLoaderPass.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
Outdated
Show resolved
Hide resolved
This shouldn't be required? |
This comment was marked as outdated.
This comment was marked as outdated.
8875176
to
f3060c0
Compare
PR updated. I added tests for the autoconfiguration. The service is registered as Twig runtime only when there are non-static methods. |
$container->registerAttributeForAutoconfiguration(AsTwigFilter::class, AttributeExtensionPass::autoconfigureFromAttribute(...)); | ||
$container->registerAttributeForAutoconfiguration(AsTwigFunction::class, AttributeExtensionPass::autoconfigureFromAttribute(...)); | ||
$container->registerAttributeForAutoconfiguration(AsTwigTest::class, AttributeExtensionPass::autoconfigureFromAttribute(...)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the attribute class is not declared (Older Twig version), this will be skipped.
symfony/src/Symfony/Component/DependencyInjection/Compiler/AttributeAutoconfigurationPass.php
Lines 58 to 62 in 6a029ec
try { | |
$attributeReflector = new \ReflectionClass($attributeName); | |
} catch (\ReflectionException) { | |
continue; | |
} |
07dcb8b
to
9adc528
Compare
…`AsTwigTest` to ease extension development (GromNaN) This PR was squashed before being merged into the 3.x branch. Discussion ---------- Create attributes `AsTwigFilter`, `AsTwigFunction` and `AsTwigTest` to ease extension development One drawback to writing extensions at present is that the declaration of functions/filters/tests is not directly adjacent to the methods. It's worse for runtime extensions because they need to be in 2 different classes. See [`SerializerExtension`](https://github.com/symfony/symfony/blob/7.0/src/Symfony/Bridge/Twig/Extension/SerializerExtension.php) and [`SerializerRuntime`](https://github.com/symfony/symfony/blob/7.0/src/Symfony/Bridge/Twig/Extension/SerializerRuntime.php) as an example. By using attributes for filters, functions and tests definition, we can make writing extensions more expressive, and use reflection to detect particular options (`needs_environment`, `needs_context`, `is_variadic`). Example if we implemented the `formatDate` filter: https://github.com/twigphp/Twig/blob/aeeec9a5e907a79e50a6bb78979154599401726e/extra/intl-extra/IntlExtension.php#L392-L395 By using the `AsTwigFilter` attribute, it is not necessary to create the `getFilters()` method. The `needs_environment` option is detected from method signature. The name is still required as the method naming convention (camelCase) doesn't match with Twig naming convention (snake_case). ```php use Twig\Extension\Attribute\AsTwigFilter; class IntlExtension { #[AsTwigFilter(name: 'format_date')] public function formatDate(Environment $env, $date, ?string $dateFormat = 'medium', string $pattern = '', $timezone = null, string $calendar = 'gregorian', string $locale = null): string { return $this->formatDateTime($env, $date, $dateFormat, 'none', $pattern, $timezone, $calendar, $locale); } } ``` This approach does not totally replace the current definition of extensions, which is still necessary for advanced needs. It does, however, make for more pleasant reading and writing. This makes writing lazy-loaded runtime extension the easiest way to create Twig extension in Symfony: symfony/symfony#52748 Related to symfony/symfony#50016 Is there any need to cache the parsing of method attributes? They are only read at compile time, but that can have a performance impact during development or when using dynamic templates. Commits ------- 5886907 Create attributes `AsTwigFilter`, `AsTwigFunction` and `AsTwigTest` to ease extension development
Twig counter-part has been merged now. |
b41b2ba
to
7cc3401
Compare
…wigTest]` attributes to configure runtime extensions
Thank you @GromNaN. |
Integration for new PHP attributes introduced by twigphp/Twig#3916.