phpsymfonytwig

Decoding JSON in Twig


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 %}

Solution

  • 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 %}