1

重複の可能性:
Symfony2 Twig 無制限の子深度

Twig 内のオブジェクトのリストをループしたい。このリストには、ある種の自己参照型の多対 1 の関係があり、次のようになります。

  • アイテム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 %}

あとは、テンプレート内からマクロを 1 回呼び出すだけです。

{{ _self.recursiveList(objects) }}

うまくいけば、誰かがこれも役に立つと思います。

于 2012-10-01T14:22:24.927 に答える