Refactor Twig extensions to use attributes for declaring functions and filters, remove AbstractExtension inheritance, and clean up related service definitions.

This commit is contained in:
2025-12-19 12:23:20 +01:00
parent 0d42ed9262
commit 741f655cfc
19 changed files with 72 additions and 244 deletions

View File

@@ -20,7 +20,7 @@ use Twig\TwigFilter;
*
* This filter replace the char " by ""
*/
class CSVCellTwig extends AbstractExtension
class CSVCellTwig
{
/**
* Replace into a string the char " by "".
@@ -29,30 +29,12 @@ class CSVCellTwig extends AbstractExtension
*
* @return string the safe string
*/
#[\Twig\Attribute\AsTwigFilter('csv_cell', isSafe: ['html'])]
public function csvCellFilter($content): string|array
{
return str_replace('"', '""', $content);
}
/**
* Returns a list of filters to add to the existing list.
*
* (non-PHPdoc)
*
* @see Twig_Extension::getFilters()
*/
#[\Override]
public function getFilters()
{
return [
new TwigFilter(
'csv_cell',
$this->csvCellFilter(...),
['is_safe' => ['html']]
),
];
}
/**
* Returns the name of the extension.
*

View File

@@ -17,7 +17,7 @@ use Twig\TwigFilter;
/**
* Render markdown.
*/
final class ChillMarkdownRenderExtension extends AbstractExtension
final class ChillMarkdownRenderExtension
{
/**
* @var \Parsedown
@@ -30,16 +30,7 @@ final class ChillMarkdownRenderExtension extends AbstractExtension
$this->parsedown->setSafeMode(true);
}
#[\Override]
public function getFilters(): array
{
return [
new TwigFilter('chill_markdown_to_html', $this->renderMarkdownToHtml(...), [
'is_safe' => ['html'],
]),
];
}
#[\Twig\Attribute\AsTwigFilter('chill_markdown_to_html', isSafe: ['html'])]
public function renderMarkdownToHtml(?string $var): string
{
return $this->parsedown->parse((string) $var);

View File

@@ -16,19 +16,8 @@ use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class ChillTwigHelper extends AbstractExtension
class ChillTwigHelper
{
#[\Override]
public function getFilters()
{
return [
new TwigFilter('chill_print_or_message', $this->printOrMessage(...), [
'needs_environment' => true,
'is_safe' => ['html', 'html_attrs'],
]),
];
}
/**
* Print `value` inside a template, or, if $value is empty,
* print $message.
@@ -49,6 +38,7 @@ class ChillTwigHelper extends AbstractExtension
* @param string $message
* @param string $template
*/
#[\Twig\Attribute\AsTwigFilter('chill_print_or_message', needsEnvironment: true, isSafe: ['html', 'html_attrs'])]
public function printOrMessage(
Environment $twig,
$value,

View File

@@ -13,9 +13,7 @@ namespace Chill\MainBundle\Templating;
use Symfony\Bridge\Twig\Extension\RoutingExtension;
use Symfony\Component\HttpFoundation\RequestStack;
use Twig\Extension\AbstractExtension;
use Twig\Node\Node;
use Twig\TwigFilter;
use Twig\TwigFunction;
/**
@@ -23,25 +21,12 @@ use Twig\TwigFunction;
*
* The logic of the function is based on the original routing extension.
*/
class ChillTwigRoutingHelper extends AbstractExtension
final readonly class ChillTwigRoutingHelper
{
/**
* @var RoutingExtension
*/
protected $originalExtension;
/**
* @var RequestStack
*/
protected $requestStack;
public function __construct(
RequestStack $requestStack,
RoutingExtension $originalExtension,
) {
$this->requestStack = $requestStack;
$this->originalExtension = $originalExtension;
}
private RequestStack $requestStack,
private RoutingExtension $originalExtension,
) {}
public function getFunctions(): array
{
@@ -75,20 +60,6 @@ class ChillTwigRoutingHelper extends AbstractExtension
return $this->originalExtension->getPath($name, $params, $relative);
}
public function getFilters(): array
{
return [
new TwigFilter('chill_return_path_label', $this->getLabelReturnPath(...)),
];
}
public function getLabelReturnPath($default)
{
$request = $this->requestStack->getCurrentRequest();
return $request->query->get('returnPathLabel', null) ?? $default;
}
/**
* Build an url with a returnPath parameter to current page.
*

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Templating;
use Symfony\Component\HttpFoundation\RequestStack;
final readonly class ChillTwigRoutingHelperLabel
{
public function __construct(
private RequestStack $requestStack,
) {}
#[\Twig\Attribute\AsTwigFilter('chill_return_path_label')]
public function getLabelReturnPath($default): string
{
$request = $this->requestStack->getCurrentRequest();
return $request->query->get('returnPathLabel', null) ?? $default;
}
}

View File

@@ -17,31 +17,17 @@ use Twig\TwigFilter;
/**
* Class ChillEntityRenderExtension.
*/
class ChillEntityRenderExtension extends AbstractExtension
class ChillEntityRenderExtension
{
public function __construct(private readonly ChillEntityRenderManagerInterface $renderManager) {}
/**
* @return array|TwigFilter[]
*/
#[\Override]
public function getFilters()
{
return [
new TwigFilter('chill_entity_render_string', $this->renderString(...), [
'is_safe' => ['html'],
]),
new TwigFilter('chill_entity_render_box', $this->renderBox(...), [
'is_safe' => ['html'],
]),
];
}
#[\Twig\Attribute\AsTwigFilter('chill_entity_render_box', isSafe: ['html'])]
public function renderBox(?object $entity, array $options = []): string
{
return $this->renderManager->renderBox($entity, $options);
}
#[\Twig\Attribute\AsTwigFilter('chill_entity_render_string', isSafe: ['html'])]
public function renderString(?object $entity, array $options = []): string
{
return $this->renderManager->renderString($entity, $options);

View File

@@ -20,28 +20,19 @@ use Twig\Error\SyntaxError;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class Templating extends AbstractExtension
class Templating
{
public function __construct(
private readonly RequestStack $requestStack,
private readonly FilterOrderGetActiveFilterHelper $filterOrderGetActiveFilterHelper,
) {}
#[\Override]
public function getFilters(): array
{
return [
new TwigFilter('chill_render_filter_order_helper', $this->renderFilterOrderHelper(...), [
'needs_environment' => true, 'is_safe' => ['html'],
]),
];
}
/**
* @throws SyntaxError
* @throws RuntimeError
* @throws LoaderError
*/
#[\Twig\Attribute\AsTwigFilter('chill_render_filter_order_helper', needsEnvironment: true, isSafe: ['html'])]
public function renderFilterOrderHelper(
Environment $environment,
FilterOrderHelper $helper,

View File

@@ -13,8 +13,8 @@ namespace Chill\MainBundle\Templating\Widget;
use Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Twig\DeprecatedCallableInfo;
use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
/**
@@ -40,7 +40,7 @@ use Twig\TwigFunction;
* `Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent`
* for usage of this event class
*/
class WidgetRenderingTwig extends AbstractExtension
class WidgetRenderingTwig
{
/**
* @var EventDispatcherInterface
@@ -83,8 +83,7 @@ class WidgetRenderingTwig extends AbstractExtension
$this->widget[$place][$ordering] = [$widget, $config];
}
#[\Override]
public function getFunctions()
public function getFunctions(): array
{
return [
new TwigFunction(
@@ -96,11 +95,6 @@ class WidgetRenderingTwig extends AbstractExtension
'deprecated' => true, 'alternative' => 'chill_widget',
]
),
new TwigFunction(
'chill_widget',
$this->renderingWidget(...),
['is_safe' => ['html'], 'needs_environment' => true]
),
];
}
@@ -109,7 +103,8 @@ class WidgetRenderingTwig extends AbstractExtension
return 'chill_main_widget';
}
public function renderingWidget(Environment $env, $block, array $context = [])
#[\Twig\Attribute\AsTwigFunction('chill_widget', needsEnvironment: true, isSafe: ['html'], deprecationInfo: new DeprecatedCallableInfo('chill-project/chill-bundles', '3.0'))]
public function renderingWidget(Environment $env, $block, array $context = []): string
{
// get the content of widgets
$content = '';