Symfony 7 — Twig extension for Stimulus values

Jakub Pradeniak
2 min readSep 22, 2024

--

EDIT:

As Jonathan pointed out, Stimulus has this functionality in stimulus_controller function, so this is more of exercise for Twig extensions 😄.

While using Stimulus with Symfony 7.1 and Twig templates I run into issue with Stimulus values.

I fount out that official Twig extension for Stimulus contains 3 Twig functions:

  • stimulus_controller
  • stimulus_target
  • stimulus_action

But there is no function for adding data attributes for Stimulus values. Luckily it is fairly easy to create our own Twig extensions, so here is the Stimulus Value Extension:

StimulusValueExtension.php:

<?php

namespace App\Twig\Extension;

use App\Twig\Runtime\StimulusValueRuntime;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class StimulusValueExtension extends AbstractExtension
{
public function getFunctions(): array
{
return [
new TwigFunction('stimulus_value', [StimulusValueRuntime::class, 'stimulusValue']),
];
}
}

StimulusValueRuntime.php:

<?php

namespace App\Twig\Runtime;

use Twig\Extension\RuntimeExtensionInterface;
use Twig\Markup;

readonly class StimulusValueRuntime implements RuntimeExtensionInterface
{
public function stimulusValue(string $controllerName, string $valueName, mixed $value): Markup
{
$processedValue = $value;
if (!is_string($value)) {
$processedValue = json_encode($value);
}

$dataAttribute = sprintf("data-%s-%s-value='%s'", $controllerName, $valueName, $processedValue);
return new Markup($dataAttribute, 'UTF-8');
}
}

And usage:

<div 
{{ stimulus_controller('controllerName') }}
{{ stimulus_value('controllerName', 'valueName', 'data') }}
>
...
</div>

The code can be also found here: https://gist.github.com/JakubPradeniak/5931c41b7b38a7bd7b63810cb714a109.

There is only one key point to keep in mind when creating Twig extensions like this — returning HTML, attributes or raw values in general — and itis the fact that Twig is processing and escaping everything we give it.

To output HTML or raw values properly we have to either use Twig'sraw filter:

{{ some_func(…)|raw }}

or to return Twig Markup — see return statement in Runtime class. This way we secure correct render of raw values without need of applying raw filter.

--

--

Jakub Pradeniak

Full-stack (React + PHP/.net) developer from Czech Republic :)