我想在Twig中循环一个对象列表。该列表具有某种自引用的多对一关系,可以如下所示:
因此实体内的定义如下:
/**
* @ORM\OneToMany(targetEntity="Item", mappedBy="parent")
*/
private $children;
/**
* @ORM\ManyToOne(targetEntity="Item", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*/
private $parent;
我知道要创建一个类似于以下内容的列表:
<ul>
<li>Item 1</li>
<li>
Item 2
<ul>
<li>Item 2 1</li>
<li>
Item 2 2
<ul>
<li>Item 2 2 1</li>
</ul>
</li>
</ul>
</li>
<li>
Item 3
<ul>
<li>Item 3 1</li>
</ul>
</li>
<li>Item 4</li>
</ul>
如何做到这一点?
答案 0 :(得分:2)
在Twig中有几种方法可以做到这一点。一个非常简单的方法是使用递归调用的宏。此宏可以放在与实际输出相同的文件中,并通过以下方式引用:{{ _self.macroname(parameters) }}
请参阅评论以获取详细说明:
<!-- send two variables to the macro: the list of objects and the current level (default/root is null) -->
{% macro recursiveList(objects, parent) %}
<!-- store, whether there's an element located within the current level -->
{% set _hit = false %}
<!-- loop through the items -->
{% for _item in objects %}
<!-- get the current parent id if applicable -->
{% set _value = ( null != _item.parent and null != _item.parent.id ? _item.parent.id : null ) %}
<!-- compare current level to current parent id -->
{% if (parent == _value) %}
<!-- if we have at least one element open the 'ul'-tag and store that we already had a hit -->
{% if not _hit %}
<ul class="tab">
{% set _hit = true %}
{% endif %}
<!-- print out element -->
<li>
{{ _item.title }}
<!-- call the macro with the new id as root/parent -->
{{ _self.recursiveList(objects, _item.id) }}
</li>
{% endif %}
{% endfor %}
<!-- if there was at least one hit, close the 'ul'-tag properly -->
{% if _hit %}
</ul>
{% endif %}
{% endmacro %}
唯一要做的就是从模板中调用宏一次:
{{ _self.recursiveList(objects) }}
希望,有人发现这也很有用。