2013-01-24 56 views
13

twigでJSONをデコードすることは可能ですか?グーグルはこれについて何も出ていないようです。 TwigでのJSONのデコードは意味をなさないでしょうか?TwigでJSONをデコードする


私はSymfony2のエンティティのフィールドタイプ()上の2つのエンティティプロパティにアクセスしようとしています。

エンティティ属性ではなくカスタマイズされた文字列を取得するためにエンティティに余分なメソッドを追加することを提案した2つの以前の質問(Symfony2 entity field type alternatives to "property" or "__toString()"?Symfony 2 Create a entity form field with 2 properties)を見てから、私はオブジェクトを表すJSON文字列を返すインスタンス。どこかのエンティティクラスの

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

とフォーム(のようなもの)に:

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

、私は小枝でそれをjson_decodeするために期待していた...

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

なぜ 'json_encode()'、それを生産するのだろうか? –

+0

はい、私は 'json_encode(get_object_vars($ this))'をします。問題はPHPではなく、Twigになければならないため、解読しています。 –

+0

私はTwig/Symfony2に慣れていませんが、あなたの行動でそれをデコードし、その結果をTwigテンプレートに渡すことができますか? – halfer

答えて

26

もしあなたが簡単なら、extend twig

まず、拡張含まれるクラスを作成:あなたの小枝テンプレートにそれを使用し、その後

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

:次に

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

を、あなたのservices.xmlファイルにそのクラスを登録します。

+0

'' json_encode''を '' json_decode ''' getFilters() 'の中に入れてはいけませんか? – cheesemacfly

+0

確かに、私は答えを更新しました。乾杯! – Xocoatzin

+2

念のために誰もがServices.ymlのセットアップを探して: 'acme_demo.twig.extension.vars_extension: クラス:アクメ\ DemoBundle \小枝\拡張\ VarsExtension 引数:[@service_container] タグ: - {名:「小枝.extension '} ' – HBK

3

私はJSONに到達する方法を考え出しました他の人に。

私の場合は、おそらく10のレコード(レイアウト)がmysql dbから返され、各行にプロパティと呼ばれるjson文字列のフィールドがあります。だから、私は簡単にレコードを引き出し、そのようにテンプレートにそれらを送信することができます:私は小枝で私の{レイアウトの%でのレイアウトの%}を行う際にこれまで

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

とても良い、しかしに方法はありませんそれらはまだjson文字列であるので、プロパティフィールド項目に到達します。

だから私は小枝テンプレートに$レイアウトを渡す直前に、私は次のようでした:

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

このアイブを行うことによっては、JSONデコードされたオブジェクトが含まれている「復号」と呼ばれる私のオブジェクト内のその場で変数を作成しました。

だから今、私のテンプレートで、私はこれは良い解決策のeveryonesの考えに少しハックしていないかもしれません{{}} layout.decoded.whatever

で私のJSONの項目にアクセスすることができます。私はうまく動作しますが、オーバヘッドはほとんどありません。テンプレートに達する前に仕事をしているので、枝を伸ばすことをやめなければなりません。

2

代替上記の全て。
これが最適なソリューションかどうかはわかりませんが、となります。

1)ヘルパー機能レジスタを作成します。

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


2)あなたの小枝ファイルでこの機能を使用してください。

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

{% for r is res %} 
    {{ r }} 
{% endfor %} 
2
Symfony2.8またはSymfony3ため

更新されたコード:私は私のエンティティでJsonArrayを持っている私の場合

<?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'), 
     ]; 
    } 
} 
0

が、私は私のエンティティでMethodeのを追加しました

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

symfony 3.1の場合、official docのように、この目的のためのヘルパーがあります:return $this->json()

/** 
* @Route("/", name="homepage") 
* @Method({"GET","POST"}) 
*/ 
public function indexAction() 
{ 
    $person = new Person(); 
    $form = $this->createForm(PersonType::class, $person,[ 
     'action'=>$this->generateUrl('homepage'), 
     'method'=>'POST' 
    ]); 
    $form->handleRequest($request); 
    if($form->isSubmitted() && $form->isValid()){ 
     return $this->json([ 
      'name'=>$person->getName(), 
      'age'=>$person->getAge() 
     ]); 
    } 
    return $this->render('default/index.html.twig',['form'=>$form->createView()]); 
} 

出力は次のようである:

{"name":"john","age":39} 
+0

ダウン-voter:議決権行使を詳しく説明しますか? –

0

これは古い質問ですが、私は...記録のために私の溶液を加えるだけで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); 

使い方:

は、Twigレンダリングを呼び出す前にa_json_variableを文字列[["1"、 "2"、 "3"、 "4"、 "5"]に設定します。

小枝テンプレート:

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

はPHPで

The values are: 1, 2, 3, 4, 5 
関連する問題