11

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.

russellmania
  • 640
  • 2
  • 8
  • 21
  • 2
    I'm personally wondering how the single quotes are traded for the double quotes in your code.. single quoted json properties are invalid. Also, whitespace isn't a requirement for valid json. – Daedalus Jan 28 '14 at 04:00
  • You're absolutely right. I asked this question too soon. Valid JSON does not require the whitespace--it does require the quotes to be around the property name of the object, which I was not doing. – russellmania Jan 28 '14 at 04:44

7 Answers7

15

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.

biera
  • 2,608
  • 1
  • 24
  • 26
6

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.

DasBaconfist
  • 606
  • 6
  • 14
4

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 }}
KoviNET
  • 717
  • 1
  • 7
  • 23
  • If one only uses said json in JavaScript, I would *highly* advise anyone to use @biera s answer, as the missing encoding here can create problems further down the line, when dealing with newlines for example. – finngu Mar 06 '23 at 11:19
3

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));
}
Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153
0

Try wrapping your template in an autoescape block:

{% autoescape 'js' %}
  { "href": "{{ my_url }}" }
{% endautoescape%}
double-beep
  • 5,031
  • 17
  • 33
  • 41
gggeek
  • 315
  • 1
  • 3
  • 8
-1

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);
    }
}
Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153
Ravi Chauhan
  • 1,409
  • 13
  • 26
-2

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();
 });
vivek
  • 309
  • 1
  • 2
  • 8