Skip to content

Commit 38b0bbd

Browse files
committed
implement twig serialize filter
1 parent d1d16d9 commit 38b0bbd

File tree

6 files changed

+155
-0
lines changed

6 files changed

+155
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.3.0
5+
-----
6+
7+
* Added a new `serialize` filter to serialize objects using the Serializer component
8+
49
5.2.0
510
-----
611

Extension/SerializerExtension.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Extension;
13+
14+
use Twig\Extension\AbstractExtension;
15+
use Twig\TwigFilter;
16+
17+
/**
18+
* @author Jesse Rushlow <[email protected]>
19+
*/
20+
final class SerializerExtension extends AbstractExtension
21+
{
22+
public function getFilters(): array
23+
{
24+
return [
25+
new TwigFilter('serialize', [SerializerRuntime::class, 'serialize']),
26+
];
27+
}
28+
}

Extension/SerializerRuntime.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Extension;
13+
14+
use Symfony\Component\Serializer\SerializerInterface;
15+
use Twig\Extension\RuntimeExtensionInterface;
16+
17+
/**
18+
* @author Jesse Rushlow <[email protected]>
19+
*/
20+
final class SerializerRuntime implements RuntimeExtensionInterface
21+
{
22+
private $serializer;
23+
24+
public function __construct(SerializerInterface $serializer)
25+
{
26+
$this->serializer = $serializer;
27+
}
28+
29+
public function serialize($data, string $format = 'json', array $context = []): string
30+
{
31+
return $this->serializer->serialize($data, $format, $context);
32+
}
33+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Symfony\Bridge\Twig\Tests\Extension\Fixtures;
4+
5+
use Symfony\Component\Serializer\Annotation\Groups;
6+
7+
/**
8+
* @author Jesse Rushlow <[email protected]>
9+
*/
10+
class SerializerModelFixture
11+
{
12+
/**
13+
* @Groups({"read"})
14+
*/
15+
public $name = 'howdy';
16+
17+
public $title = 'fixture';
18+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Tests\Extension;
13+
14+
use Doctrine\Common\Annotations\AnnotationReader;
15+
use PHPUnit\Framework\TestCase;
16+
use Symfony\Bridge\Twig\Extension\SerializerExtension;
17+
use Symfony\Bridge\Twig\Extension\SerializerRuntime;
18+
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\SerializerModelFixture;
19+
use Symfony\Component\Serializer\Encoder\JsonEncoder;
20+
use Symfony\Component\Serializer\Encoder\YamlEncoder;
21+
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
22+
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
23+
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
24+
use Symfony\Component\Serializer\Serializer;
25+
use Twig\Environment;
26+
use Twig\Loader\ArrayLoader;
27+
use Twig\RuntimeLoader\RuntimeLoaderInterface;
28+
29+
/**
30+
* @author Jesse Rushlow <[email protected]>
31+
*/
32+
class SerializerExtensionTest extends TestCase
33+
{
34+
/**
35+
* @dataProvider serializerDataProvider
36+
*/
37+
public function testSerializeFilter(string $template, string $expectedResult)
38+
{
39+
$twig = $this->getTwig($template);
40+
41+
self::assertSame($expectedResult, $twig->render('template', ['object' => new SerializerModelFixture()]));
42+
}
43+
44+
public function serializerDataProvider(): \Generator
45+
{
46+
yield ['{{ object|serialize }}', '{&quot;name&quot;:&quot;howdy&quot;,&quot;title&quot;:&quot;fixture&quot;}'];
47+
yield ['{{ object|serialize(\'yaml\') }}', '{ name: howdy, title: fixture }'];
48+
yield ['{{ object|serialize(\'yaml\', {groups: \'read\'}) }}', '{ name: howdy }'];
49+
}
50+
51+
private function getTwig(string $template): Environment
52+
{
53+
$meta = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
54+
$runtime = new SerializerRuntime(new Serializer([new ObjectNormalizer($meta)], [new JsonEncoder(), new YamlEncoder()]));
55+
56+
$mockRuntimeLoader = $this->createMock(RuntimeLoaderInterface::class);
57+
$mockRuntimeLoader
58+
->method('load')
59+
->willReturnMap([
60+
['Symfony\Bridge\Twig\Extension\SerializerRuntime', $runtime],
61+
])
62+
;
63+
64+
$twig = new Environment(new ArrayLoader(['template' => $template]));
65+
$twig->addExtension(new SerializerExtension());
66+
$twig->addRuntimeLoader($mockRuntimeLoader);
67+
68+
return $twig;
69+
}
70+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"twig/twig": "^2.13|^3.0.4"
2323
},
2424
"require-dev": {
25+
"doctrine/annotations": "^1.12",
2526
"egulias/email-validator": "^2.1.10",
2627
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
2728
"symfony/asset": "^4.4|^5.0",

0 commit comments

Comments
 (0)