russellmania
russellmania

Reputation: 749

Using Twig to generate JSON

I want to have a URL that returns a simple JSON object. I am trying to use Twig to generate the JSON object:

{
"urls": [
{% for child in page.root %}
    "{{ child.url }}"{% if not loop.last %},{% endif %}
{% endfor %}
]
}

The carriage returns will not remain in place though, and I keep getting a result that looks like this:

{'urls':['../ants/','../brick-report/','../the-pollution-intervention/','../barclay/','../broken-advertising/','../aldat-n-densom/','../thisisart/','../there-she-goes-again/']}

which Jquery will not parse with it's ajax or getJSON methods. It's totally ignoring this JSON. How might I convince Twig to put the right whitespace in place? I've looked at the manual and it only seems concerned with NOT inserting whitespace.

Upvotes: 12

Views: 40309

Answers (7)

biera
biera

Reputation: 2699

This works for me (twig template):

var parsedJSON = JSON.parse('{{ ['one', 'two', 'three']|json_encode|e('js') }}');

And this:

console.log(parsedJSON);

outputs:

 Array ["one", "two", "three"]

in browser's console.

Upvotes: 16

KoviNET
KoviNET

Reputation: 819

Generally it would make more sense to make controller return json directly, by returning JsonRespnse object

But if you really need to output JSON in Twig and assign it to variable, you can also use:

let foo = {{ bar|json_encode|raw }}

Upvotes: 6

gggeek
gggeek

Reputation: 331

Try wrapping your template in an autoescape block:

{% autoescape 'js' %}
  { "href": "{{ my_url }}" }
{% endautoescape%}

Upvotes: 1

Alain
Alain

Reputation: 36984

Don't use Twig to generate your json response.

In your controller, use:

return new Response(json_encode($var));

Sample:

public function sampleAction()
{
    $urls = array('../test', '../something', '../sample');
    return new Response(json_encode($var));
}

If URLs are generated from Symfony2 routes, you can use:

public function sampleAction()
{
    $urls = array(
             $this->generateUrl('my_test'),
             $this->generateUrl('my_something'),
             $this->generateUrl('my_sample'),
    );
    return new Response(json_encode($var));
}

Upvotes: 3

Ravi Chauhan
Ravi Chauhan

Reputation: 1477

Thats 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);
    }
}

Upvotes: -1

DasBaconfist
DasBaconfist

Reputation: 604

Twig has a filter for this.

json_encode, it uses PHP json_encode function.

for your case:

{{ {'urls': page.root}|json_encode }}

will output

{"urls":["..\/ants\/","..\/brick-report\/","..\/the-pollution-intervention\/","..\/barclay\/","..\/broken-advertising\/","..\/aldat-n-densom\/","..\/thisisart\/","..\/there-she-goes-again\/"]}

the code is tested and works. For more information take a look at the Twig Documentation for json_encode.

Upvotes: 6

vivek
vivek

Reputation: 329

Basically the $.getJson() method requires json but ther is a string so you can use $.get() to get the response and use the parser to parse the string to JSON

 $.get("ffff",function(data){
 // user parser
 JSON.parse();
 });

Upvotes: -2

Related Questions