feature #40323 [TwigBridge][TwigBundle] Twig serialize filter (jrushlow)
This PR was merged into the 5.3-dev branch.
Discussion
----------
[TwigBridge][TwigBundle] Twig serialize filter
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | Fix #40227
| License | MIT
| Doc PR | symfony/symfony-docs#15039
Adds a new `serialize` filter for Twig utilizing the Serializer component. As suggested in #40227 - would allow you to pass a serialized object to the front end without needing to make an ajax call.
Commits
-------
abb534ab56
implement twig serialize filter
This commit is contained in:
commit
3a92844519
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
5.3.0
|
||||
-----
|
||||
|
||||
* Added a new `serialize` filter to serialize objects using the Serializer component
|
||||
|
||||
5.2.0
|
||||
-----
|
||||
|
||||
|
28
src/Symfony/Bridge/Twig/Extension/SerializerExtension.php
Normal file
28
src/Symfony/Bridge/Twig/Extension/SerializerExtension.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Twig\Extension;
|
||||
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
/**
|
||||
* @author Jesse Rushlow <jr@rushlow.dev>
|
||||
*/
|
||||
final class SerializerExtension extends AbstractExtension
|
||||
{
|
||||
public function getFilters(): array
|
||||
{
|
||||
return [
|
||||
new TwigFilter('serialize', [SerializerRuntime::class, 'serialize']),
|
||||
];
|
||||
}
|
||||
}
|
33
src/Symfony/Bridge/Twig/Extension/SerializerRuntime.php
Normal file
33
src/Symfony/Bridge/Twig/Extension/SerializerRuntime.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Twig\Extension;
|
||||
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
/**
|
||||
* @author Jesse Rushlow <jr@rushlow.dev>
|
||||
*/
|
||||
final class SerializerRuntime implements RuntimeExtensionInterface
|
||||
{
|
||||
private $serializer;
|
||||
|
||||
public function __construct(SerializerInterface $serializer)
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
|
||||
public function serialize($data, string $format = 'json', array $context = []): string
|
||||
{
|
||||
return $this->serializer->serialize($data, $format, $context);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Bridge\Twig\Tests\Extension\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
/**
|
||||
* @author Jesse Rushlow <jr@rushlow.dev>
|
||||
*/
|
||||
class SerializerModelFixture
|
||||
{
|
||||
/**
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
public $name = 'howdy';
|
||||
|
||||
public $title = 'fixture';
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Twig\Tests\Extension;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\Twig\Extension\SerializerExtension;
|
||||
use Symfony\Bridge\Twig\Extension\SerializerRuntime;
|
||||
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\SerializerModelFixture;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Symfony\Component\Serializer\Encoder\YamlEncoder;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
||||
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\ArrayLoader;
|
||||
use Twig\RuntimeLoader\RuntimeLoaderInterface;
|
||||
|
||||
/**
|
||||
* @author Jesse Rushlow <jr@rushlow.dev>
|
||||
*/
|
||||
class SerializerExtensionTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider serializerDataProvider
|
||||
*/
|
||||
public function testSerializeFilter(string $template, string $expectedResult)
|
||||
{
|
||||
$twig = $this->getTwig($template);
|
||||
|
||||
self::assertSame($expectedResult, $twig->render('template', ['object' => new SerializerModelFixture()]));
|
||||
}
|
||||
|
||||
public function serializerDataProvider(): \Generator
|
||||
{
|
||||
yield ['{{ object|serialize }}', '{"name":"howdy","title":"fixture"}'];
|
||||
yield ['{{ object|serialize(\'yaml\') }}', '{ name: howdy, title: fixture }'];
|
||||
yield ['{{ object|serialize(\'yaml\', {groups: \'read\'}) }}', '{ name: howdy }'];
|
||||
}
|
||||
|
||||
private function getTwig(string $template): Environment
|
||||
{
|
||||
$meta = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||
$runtime = new SerializerRuntime(new Serializer([new ObjectNormalizer($meta)], [new JsonEncoder(), new YamlEncoder()]));
|
||||
|
||||
$mockRuntimeLoader = $this->createMock(RuntimeLoaderInterface::class);
|
||||
$mockRuntimeLoader
|
||||
->method('load')
|
||||
->willReturnMap([
|
||||
['Symfony\Bridge\Twig\Extension\SerializerRuntime', $runtime],
|
||||
])
|
||||
;
|
||||
|
||||
$twig = new Environment(new ArrayLoader(['template' => $template]));
|
||||
$twig->addExtension(new SerializerExtension());
|
||||
$twig->addRuntimeLoader($mockRuntimeLoader);
|
||||
|
||||
return $twig;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
"twig/twig": "^2.13|^3.0.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/annotations": "^1.12",
|
||||
"egulias/email-validator": "^2.1.10",
|
||||
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
|
||||
"symfony/asset": "^4.4|^5.0",
|
||||
|
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
5.3.0
|
||||
-----
|
||||
|
||||
* Added support for the new `serialize` filter (from Twig Bridge)
|
||||
|
||||
5.2.0
|
||||
-----
|
||||
|
||||
@ -33,7 +38,7 @@ CHANGELOG
|
||||
4.1.0
|
||||
-----
|
||||
|
||||
* added priority to Twig extensions
|
||||
* added priority to Twig extensions
|
||||
* deprecated relying on the default value (`false`) of the `twig.strict_variables` configuration option. The `%kernel.debug%` parameter will be the new default in 5.0
|
||||
|
||||
4.0.0
|
||||
|
@ -120,5 +120,10 @@ class ExtensionPass implements CompilerPassInterface
|
||||
} else {
|
||||
$container->getDefinition('workflow.twig_extension')->addTag('twig.extension');
|
||||
}
|
||||
|
||||
if ($container->has('serializer')) {
|
||||
$container->getDefinition('twig.runtime.serializer')->addTag('twig.runtime');
|
||||
$container->getDefinition('twig.extension.serializer')->addTag('twig.extension');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ use Symfony\Bridge\Twig\Extension\HttpKernelExtension;
|
||||
use Symfony\Bridge\Twig\Extension\HttpKernelRuntime;
|
||||
use Symfony\Bridge\Twig\Extension\ProfilerExtension;
|
||||
use Symfony\Bridge\Twig\Extension\RoutingExtension;
|
||||
use Symfony\Bridge\Twig\Extension\SerializerExtension;
|
||||
use Symfony\Bridge\Twig\Extension\SerializerRuntime;
|
||||
use Symfony\Bridge\Twig\Extension\StopwatchExtension;
|
||||
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||
use Symfony\Bridge\Twig\Extension\WebLinkExtension;
|
||||
@ -160,5 +162,10 @@ return static function (ContainerConfigurator $container) {
|
||||
->factory([TwigErrorRenderer::class, 'isDebug'])
|
||||
->args([service('request_stack'), param('kernel.debug')]),
|
||||
])
|
||||
|
||||
->set('twig.runtime.serializer', SerializerRuntime::class)
|
||||
->args([service('serializer')])
|
||||
|
||||
->set('twig.extension.serializer', SerializerExtension::class)
|
||||
;
|
||||
};
|
||||
|
Reference in New Issue
Block a user