Is is possible to decode JSON in twig? Googling doesn't seem to yield anything about this. Does decoding JSON in Twig not make sense?
I'm trying to access 2 entity properties on an Symfony2's entity field type (Entity Field Type).
After coming across 2 previous SO questions ( Symfony2 entity field type alternatives to "property" or "__toString()"? and Symfony 2 Create a entity form field with 2 properties ) which suggested adding an extra method to an entity to retrieve a customized string rather than an entity attribute, I thought of (and did) returning a JSON string representing an object instance.
Somewhere in the entity class:
/**
* Return a JSON string representing this class.
*/
public function getJson()
{
return json_encode(get_object_vars($this));
}
And in the form (something like):
$builder->add('categories', 'entity', array (
...
'property' => 'json',
...
));
Afterwards, I was hoping to json_decode
it in Twig...
{% for category in form.categories %}
{# json_decode() part is imaginary #}
{% set obj = category.vars.label|json_decode() %}
{% endfor %}
That's easy if you extend twig.
First, create a class that will contain the extension:
<?php
namespace Acme\DemoBundle\Twig\Extension;
use Symfony\Component\DependencyInjection\ContainerInterface;
use \Twig_Extension;
class VarsExtension extends Twig_Extension
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getName()
{
return 'some.extension';
}
public function getFilters() {
return array(
'json_decode' => new \Twig_Filter_Method($this, 'jsonDecode'),
);
}
public function jsonDecode($str) {
return json_decode($str);
}
}
Then, register that class in your Services.xml
file:
<service id="some_id" class="Acme\DemoBundle\Twig\Extension\VarsExtension">
<tag name="twig.extension" />
<argument type="service" id="service_container" />
</service>
Then, use it on your twig templates:
{% set obj = form_label(category) | json_decode %}
I came up with a way of getting to my JSON and I thought I'd share it here in case its usefult to someone else.
so in my case I have maybe 10 records (layouts) returned from a mysql db and each row has a field called properties which is a json string. So, I can easily pull out the records and send them to the template like so:
echo $twig->render('template.html.twig', array(
"layouts" => $layouts,
));
So far so good, However when I do my {% for layout in layouts %} in twig there is no way to get to the properties field items as they are still a json string.
So just before I passed $layouts to the twig template I did the following:
foreach($layouts as $i => $v)
{
$layouts[$i]->decoded = json_decode($v->getProperties());
}
by doing this Ive created a variable on the fly within my object called 'decoded' which contains the json decoded object.
So now in my template I can access my json items by {{ layout.decoded.whatever }}
This might be a bit hacky and not to everyones idea of a good solution. I works well for me, very little overhead and means I dont have to mess about with extending twig as Im doing the work before it gets to the template.
An alternative to all above.
And I don't know whether this is the optimal solution, but it works.
1) Create a helper function and register that function it.
<?php
function twig_json_decode($json)
{
return json_decode($json, true);
}
2) Use this function in your twig file.
{% set res = twig_json_decode(json) %}
# above will return an array which can be iterated
{% for r is res %}
{{ r }}
{% endfor %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With