1

可能重复:
Symfony2 Twig 无限子深度

我想遍历 Twig 中的对象列表。该列表具有某种自引用的多对一关系,如下所示:

  • 项目 1
  • 第 2 项
    • 项目 2 1
    • 项目 2 2
      • 项目 2 2 1
  • 第 3 项
    • 项目 3 1
  • 第 4 项

因此实体内的定义如下所示:

/**
 * @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>

如何才能做到这一点?

4

1 回答 1

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

希望,也有人觉得这很有用。

于 2012-10-01T14:22:24.927 回答