web-dev-qa-db-fra.com

Décodage de JSON dans Twig

Est-il possible de décoder JSON dans twig? Googler ne semble rien céder à ce sujet. Décoder JSON dans Twig n'a pas de sens?


J'essaie d'accéder à 2 propriétés d'entité sur un type de champ d'entité Symfony2 ( Type de champ d'entité ).

Après avoir rencontré 2 questions SO précédentes (types de champ d'entité Symfony2 autres que "propriété" ou "__toString ()"? Et Symfony 2 Créer un champ de formulaire d'entité avec 2 propriétés ) En ajoutant une méthode supplémentaire à une entité pour récupérer une chaîne personnalisée plutôt qu'un attribut d'entité, j'ai pensé retourner (et renvoyait) une chaîne JSON représentant une instance d'objet.

Quelque part dans la classe d'entité:

/**
 * Return a JSON string representing this class.
 */
public function getJson()
{
   return json_encode(get_object_vars($this));
}

Et sous la forme (quelque chose comme):

$builder->add('categories', 'entity', array (
...
'property' => 'json',
...
));

Ensuite, j'espérais le json_decode dans Twig ...

{% for category in form.categories %}
    {# json_decode() part is imaginary #}
    {% set obj = category.vars.label|json_decode() %}
{% endfor %}
22
Czar Pino

Cest facile si vous prolongez Rameau .

Tout d'abord, créez une classe qui contiendra l'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);
    }
}

Ensuite, enregistrez cette classe dans votre fichier Services.xml:

<service id="some_id" class="Acme\DemoBundle\Twig\Extension\VarsExtension">
        <tag name="twig.extension" />
        <argument type="service" id="service_container" />
</service>

Ensuite, utilisez-le sur vos modèles de brindille:

{% set obj = form_label(category) | json_decode %}
35
Xocoatzin

Un alternative à tout ce qui précède.
Et je ne sais pas si c’est la solution optimale, mais cela fonctionne .

1) Créez une fonction helper et register qui la fonctionne.

<?php
function twig_json_decode($json)
{
    return json_decode($json, true);
}


2) Utilisez cette fonction dans votre fichier twig.

{% set res = twig_json_decode(json) %}
# above will return an array which can be iterated

{% for r is res %}
    {{ r }}
{% endfor %}
5

Je suis venu avec un moyen d'obtenir mon JSON et j'ai pensé que je le partagerais ici au cas où il serait utile à quelqu'un d'autre.

donc dans mon cas, j'ai peut-être 10 enregistrements (mises en page) renvoyés par une base de données mysql et chaque ligne a un champ appelé propriétés qui est une chaîne json. Ainsi, je peux facilement extraire les enregistrements et les envoyer au modèle de la manière suivante:

echo $twig->render('template.html.twig', array(
      "layouts" => $layouts,
));

Jusqu'ici, tout va bien. Cependant, lorsque je fais mon {% pour la disposition dans les dispositions%} dans twig, il est impossible d'accéder aux éléments du champ de propriétés, car ils sont toujours une chaîne json.

Donc juste avant de passer $ layouts au template twig, j'ai fait ce qui suit:

foreach($layouts as $i => $v)
{
      $layouts[$i]->decoded = json_decode($v->getProperties());
}

en faisant cela, j'ai créé une variable à la volée au sein de mon objet appelée 'décodée' qui contient l'objet décodé JSON.

Alors maintenant, dans mon modèle, je peux accéder à mes éléments json par {{layout.decoded.w Whatever}}

Cela pourrait être un peu hacky et pas à tout le monde l’idée d’une bonne solution. Je travaille bien pour moi, très peu de frais généraux et signifie que je n'ai pas à me soucier d'étendre une brindille car je fais le travail avant d'arriver au modèle.

4
azzy81

Code mis à jour pour Symfony2.8 ou Symfony3:

<?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';
    }

    // Note: If you want to use it as {{ json_decode(var) }} instead of 
    // {{ var|json_decode }} please use getFunctions() and 
    // new \Twig_SimpleFunction('json_decode', 'json_decode') 
    public function getFilters() {
        return [
            // Note that we map php json_decode function to 
            // extension filter of the same name
            new \Twig_SimpleFilter('json_decode', 'json_decode'),
        ];
    }
}
2
Chris Hasiński

C'est une vieille question mais j'ajoute ma solution pour l'enregistrement ... Il suffit d'étendre Twig avec une SimpleFunction:

// Return a string of separated values from a JSON string
// Can optionally specify a separator.  If none provided, ", " is used.
$function = new Twig_SimpleFunction('json_to_list', function($json, $separator = ", ")
{
    $result = "";
    $array = json_decode($json, true);
    foreach ($array as $item)
    {
        if ($result != "") { $result .= $separator; }           
        $result .= $item;
    }
    return $result;
});
$twig->addFunction($function);

Usage:

définissez a_json_variable sur la chaîne '["1", "2", "3", "4", "5"] avant d'appeler le rendu Twig.

Modèle de brindille:

The values are: {{ json_to_list(a_json_variable) }}

Produira

The values are: 1, 2, 3, 4, 5
0
Ryan Griggs

Dans mon cas, j'ai un JsonArray dans mon entité, alors j'ai ajouté une méthode à mon entité.

<?php
namespace ACME\DefaultBundle\Entity;
/*...*/    
public function getDecodedPath()
{
    return json_decode($this->path);
}
0
S.Alfano