Twigのドキュメントで、次の方法で連想配列を反復処理できることを読みました。
{% for key, value in array %}
{{key}}
{{value}}
{% endfor %}
stdClass型のオブジェクトでもこれが可能かどうか疑問に思いました。
Twigが、プロパティ名をキーとしてオブジェクトのプロパティ値を反復処理することを期待していました。代わりに、forループに含まれる命令ブロックはまったく実行されません。
最初にオブジェクトを配列にキャストできます。オブジェクトを配列にキャストする独自のフィルターを作成できます。フィルタの詳細については、こちらをご覧ください:http ://twig.sensiolabs.org/doc/advanced.html#filters
その場合、次のようになります。
{% for key, value in my_object|cast_to_array %}
ここでタデックの答えを完成させる方法は次のとおりです。
Twig拡張機能(フィルター)を作成またはセットアップしたことがない場合は、最初にこの手順に従う必要がありますhttp://symfony.com/doc/2.7/cookbook/templating/twig_extension.html
1)AppBundle / Twig / AppExtension.php('cast_to_array')に追加します
public function getFilters()
{
return array(
new \Twig_SimpleFilter('md2html', array($this, 'markdownToHtml'), array('is_safe' => array('html'))),
new \Twig_SimpleFilter('price', array($this, 'priceFilter')),
new \Twig_SimpleFilter('cast_to_array', array($this, 'objectFilter')),
);
}
2)AppBundle / Twig/AppExtension.phpに追加します
public function objectFilter($stdClassObject) {
// Just typecast it to an array
$response = (array)$stdClassObject;
return $response;
}
3)example.html.twigで、小枝とフィルターを使用してループスルーします。
{% for key, value in row|cast_to_array %}
<td id="col" class="hidden-xs">{{ value }}</td>
{% endfor %}
完了しました。お役に立てば幸いです。タデックのポインターから。
TWIGをロードした後、次のフィルターを追加します。
$twig->addFilter( new Twig_SimpleFilter('cast_to_array', function ($stdClassObject) {
$response = array();
foreach ($stdClassObject as $key => $value) {
$response[] = array($key, $value);
}
return $response;
}));
Tadeckの提案にちなんでcast_to_arrayという名前が付けられています。:)どの種類のstdClassオブジェクトでも機能しないと確信していますが、PHP連想配列の印刷に関する問題は確実に解決しました:)次のように使用してください。
{% for key, value in my_object|cast_to_array %}
<td>{{ value.1 }}</td>
{% endfor %}
このSOページに頻繁にアクセスしたので、オブジェクトのプロパティを反復処理するためにTwigを使用している場所を示すのが適切だと思います。したがって、同じ問題を抱えている他の人にも役立ちます。.jsonからテーブルを印刷しようとしていました。ソースですが、PHPのjson_decodeは、任意の「キー」:「値」をPHP連想配列に変換します。これは、Twigがデフォルトで出力しません。したがって、このフィルターは、Twigが使用する通常の配列をカットして提供します。
{
"user": {
"family": {
"table": [{
"First_Name": "John",
"Last_Name": "Foo",
"Age": 25,
"Role": "Brother"
}, {
"First_Name": "Mary",
"Last_Name": "Bar",
"Age": 14,
"Role": "Sister"
}, {
"First_Name": "Joe",
"Last_Name": "Baz",
"Age": 33,
"Role": "Uncle"
}]
}
}
}
<table>
<thead>
<tr> {# get table headers from the table row #}
{% for row in user.family.table.0|cast_to_array %}
<th>{{ row.0 | replace({'_': ' '}) }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in user.family.table %}
<tr>
{% for key, value in row|cast_to_array %}
<td>{{ value.1 }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
私はこれが古いことを知っていますが、そうではありません
$assoc_array = json_decode(json_encode($stdClassObject), TRUE);
同様に機能しますか?
これが他の誰かを助ける場合に備えて。PHPのIteratorインターフェースを実装していれば、Twigにオブジェクトのプロパティを反復させることができます。
私の場合、汎用オブジェクトがあり、キーと値のペアをプライベート配列に格納するときに、マジックメソッド__get()、__ set()、__ isset()、および__unset()を使用します。これは、次のようなものを使用してオブジェクトを反復処理するまで、Twigで正常に機能します。
<ul>
{% for prop, value in object %}
<li>{{prop|replace({'_': ' '})|title}}</li>
{% endfor %}
</ul>
それを機能させるには、Iteratorインターフェースを実装する必要がありました。その後、上記のコードは完全に機能しました。
魔法の__get()により、プロパティ名でも大文字と小文字が区別されないため、これらのそれぞれも機能します。
<ul>
{% for object in arrayOfObjects %}
<li>{{ object.property }}</li>
<li>{{ object.Property }}</li>
<li>{{ object.PROPERTY }}</li>
{% endfor %}
</ul>
{% for key, item in content.field_invoice_no if key|first != '#' %} <tr>
<td>{{ item }}</td>
<td> {{ content.field_invoice_date[key] }} </td>
<td> {{ content.field_invoice_price[key] }} </td>
</tr>
{% endfor %}
キー値に対するオブジェクトの反復
私はついにバニラの小枝の解決策を見つけました。私はreduceフィルターを利用して、オブジェクトを配列に変換します。
バックエンドからアドレスオブジェクトを取得し、各行を個別にレンダリングするためにそれを連想配列に変換したいとします。
{% set address = { firstName: 'Stack', lastName: 'Overflow', address: 'here', zipCode: '1234' } %}
キーを減らして空の配列に追加します
{% set addressLines = address|keys|reduce((carry, key) => carry|merge({ (key): attribute(address, key) }), []) %}
これにより、次のようになります。
[ 'firstName' => 'Stack', 'lastName' => 'Overflow', 'address'=> 'here', 'zipCode' => '1234' ]
これで、これをforループでレンダリングできます
{% set allowedKeys = ['firstName', 'lastName', 'address'] %}
{% for key, line in addressLines|filter((v, k) => k in allowedKeys) %}
{{ line }}<br/>
{% endfor %}