You can try something like {do printf('%s',json_encode($object)) }
printf isn't restricted unlike echo and print within the context of the php and do tags. Even if it was restricted, you can define your own function and have it echo from there.
But it looks like noescape
is a very special filter which doesn't actually appear in the core filter list, it is the compiler/nodes and essential/nodes sections which check in multiple places for the presence of the noescape filter within the filter list then make decisions based on it.
➜ latte grep -r 'noescape' .
./latte/src/Latte/Essential/Nodes/BlockNode.php: if ($node->modifier->hasFilter('noescape') && count($node->modifier->filters) === 1) {
./latte/src/Latte/Essential/Nodes/BlockNode.php: throw new CompileException('Filter |noescape is not expected here.', $tag->position);
./latte/src/Latte/Essential/Nodes/IncludeFileNode.php: $noEscape = $this->modifier->hasFilter('noescape');
./latte/src/Latte/Essential/Nodes/IncludeBlockNode.php: $noEscape = $this->modifier->hasFilter('noescape');
./latte/src/Latte/Compiler/Nodes/Php/FilterNode.php: NoEscape = 'noescape';
./latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php: } elseif ($name === 'noescape') {
./latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php: if ($name === 'noescape') {
./latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php: $noescape = true;
./latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php: if ($this->escape && empty($noescape)) {
➜ latte
I'm afraid trying to find a simple way to do this without having to use noescape would push latte to its limits.
It might be possible to dynamically slap on the noescape filter if your extension finds the json_encode filter being used. Otherwise it looks like the way to do this is like so:
{$object|escapeJs|noescape}
You could also try a different syntax like:
{do json_encode_output($object) }
and define a global function like so:
function json_encode_output($object)
{
echo json_encode($object);
}
It might also be possible to define your own tag like:
{json $output}
But considering how latte is designed, I'd probably just settle with the more verbose:
{$object|escapeJs|noescape}
Or I might actually reach for:
{json_encode($object)|noescape}
Edit:
I think I actually just figured it out. Simply echo from your function.
public static function json_encode(FilterInfo $info, mixed $value): string {
echo json_encode($value);
return '';
}