Twig에서 나무를 렌더링하는 방법


90

깊이가 결정되지 않은 나무를 렌더링하고 싶습니다 (자녀의 자식 등). 배열을 재귀 적으로 반복해야합니다. Twig에서 어떻게 할 수 있습니까?

답변:


117

나는 domi27의 아이디어를 가지고 놀았고 이것을 생각해 냈습니다. 내 트리로 중첩 배열을 만들었습니다. [ 'link'] [ 'sublinks']는 null이거나 더 많은 다른 배열입니다.

템플릿

재귀 할 하위 템플릿 파일 :

<!--includes/menu-links.html-->
{% for link in links %}
    <li>
        <a href="{{ link.href }}">{{ link.name }}</a>
        {% if link.sublinks %}
            <ul>
                {% include "includes/menu-links.html" with {'links': link.sublinks} %}
            </ul>
        {% endif %}
    </li>
{% endfor %}

그런 다음 기본 템플릿에서 다음을 호출합니다 (일종의 중복 된 'with'항목).

<ul class="main-menu">
    {% include "includes/menu-links.html" with {'links':links} only %}
</ul>

매크로

매크로를 사용하여 유사한 효과를 얻을 수 있습니다.

<!--macros/menu-macros.html-->
{% macro menu_links(links) %}
    {% for link in links %}
        <li>
            <a href="{{ link.href }}">{{ link.name }}</a>
            {% if link.sublinks %}
                <ul>
                    {{ _self.menu_links(link.sublinks) }}
                </ul>
            {% endif %}
        </li>
    {% endfor %}
{% endmacro %}

기본 템플릿에서 다음을 수행합니다.

{% import "macros/menu-macros.html" as macros %}
<ul class="main-menu">
    {{ macros.menu_links(links) }}
</ul>

9
아주 좋아요, 감사합니다! 같은 템플릿에서 매크로를 사용하려면을 사용할 수 있습니다 {{ _self.menu_links(links) }}.
독감

감사합니다. 생각이 제 머리를 아프게했지만 당신의 대답은 완벽합니다.
azzy81 2013-08-21

내 프로젝트에 의견이있는 한 가지 문제가있었습니다. 서브 코멘트 (서브 링크)도 메인 컬렉션 (링크)에 포함되었습니다. 그래서 포함하기 전에 댓글에 '부모'항목이 있는지 확인해야했습니다.
Jevgeni Smirnov

4
사용 {{_self.menu_links}}나쁜 습관입니다 ! 여기에서 메모를 읽으십시오. macro 매크로 를 사용할 템플릿에 매크로를 정의 할 때 매크로를 가져 오는 대신 _self.input ()을 통해 직접 호출하고 싶을 수 있습니다. 작동하는 것처럼 보이지만 이는 현재 구현의 부작용 일 뿐이며 Twig 2.x에서는 더 이상 작동하지 않습니다. 매크로를 다시 한 번 사이트 내에서 로컬로 가져와야합니다menu_links
dr.scre 2014

37

나뭇 가지 2.0-2.11

동일한 템플릿에서 매크로 를 사용하려면 Twig 2.x와 호환되도록 다음과 같은 것을 사용해야합니다 .

{% macro menu_links(links) %}
    {% import _self as macros %}
    {% for link in links %}
        <li>
            <a href="{{ link.href }}">{{ link.name }}</a>
            {% if link.sublinks %}
                <ul>
                    {{ macros.menu_links(link.sublinks) }}
                </ul>
            {% endif %}
        </li>
    {% endfor %}
{% endmacro %}

{% import _self as macros %}

<ul class="main-menu">
    {{ macros.menu_links(links) }}
</ul>

이것은 random-coder의 대답을 확장 하고 현재 사용할 매크로대한 Twig 문서에dr.scre 의 힌트를 통합 하지만 로컬로 가져옵니다._self

나뭇 가지> = 2.11

현재 나뭇 가지 2.11 , 당신은 생략 할 수 {% import _self as macros %}인라인 매크로가 아래에 자동으로 가져로, _self네임 스페이스 (참조 나뭇 가지 발표 : 자동 매크로 가져 오기 ) :

{# {% import _self as macros %} - Can be removed #}

<ul class="main-menu">
    {{ _self.menu_links(links) }} {# Use _self for inlined macros #}
</ul>

2

PHP 5.4 이상을 실행하는 경우 Alain Tiemblo가이 문제에 대한 멋진 새 솔루션 (2016 년 5 월 기준)이 있습니다. https://github.com/ninsuo/jordan-tree .

이 정확한 목적을 제공하는 "트리"태그입니다. 마크 업은 다음과 같습니다.

{% tree link in links %}
    {% if treeloop.first %}<ul>{% endif %}

    <li>
        <a href="{{ link.href }}">{{ link.name }}</a>
        {% subtree link.sublinks %}
    </li>

    {% if treeloop.last %}</ul>{% endif %}
{% endtree %}

1
추가 변수를에 전달할 수 없습니다 subtree. 필자의 경우 코드는 더 많은 자식이 있을지 여부를 알아야하며 레벨 수를 매크로에 전달하여 <div class="{{ classes[current_level].wrapper }} {% if levels > current_level %}accordion-wrapper{% endif %}">. 이를 계산하려면 자식이 있는지 여부를 캡처하기 위해 현재 수준을 두 번 반복해야합니다.
chx apr

1

처음에는 이것이 간단한 방법으로 해결 될 수 있다고 생각했지만 그렇게 쉽지는 않습니다.

Twig 서브 템플릿을 포함 할시기와 포함하지 않을 때는 PHP 클래스 메서드를 사용하여 논리를 만들어야합니다.

<!-- tpl.html.twig -->
<ul>
    {% for key, item in menu %}
        {# Pseudo Twig code #}
        {% if item|hassubitem %}
            {% include "subitem.html.tpl" %}
        {% else %}
            <li>{{ item }}</li>
        {% endif %}
    {% endfor %}
</ul>

따라서 Twig for 루프 내에서 사용할 수 있는 특수 Twig 루프 변수 를 사용할 수 있습니다 . 하지만이 루프 변수 의 범위에 대해 잘 모르겠습니다 .

이 정보와 기타 정보는 Twigs "for"Docu 에서 확인할 수 있습니다 !


1

독감의 답변을 하고 그것을 조금 수정 :

{# Macro #}

{% macro tree(items) %}
    {% import _self as m %}
        {% if items %}
        <ul>
            {% for i in items %}
                <li>
                    <a href="{{ i.url }}">{{ i.title }}</a>
                    {{ m.tree(i.items) }}
                </li>
            {% endfor %}
        </ul>
    {% endif %}
{% endmacro %}

{# Usage #}

{% import 'macros.twig' as m %}

{{ m.tree(items) }}

-1

여기에 대한 대답은 내 솔루션으로 이어집니다.

자체 참조 다 대일 연결 (자녀의 부모)이있는 범주 엔터티가 있습니다.

/**
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
 */
private $parent;

/**
 * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
 */
private $children;

내 Twig 템플릿에서 다음과 같이 트리 뷰를 렌더링합니다.

<ul>
{% for category in categories %}
    {% if category.parent == null %}
        <li>
            <a href="{{ category.id }}">{{ category.name }}</a>
            {% if category.children|length > 0 %}
            <ul>
            {% for category in category.children %}
                <li>
                    <a href="{{ category.id }}">{{ category.name }}</a>
                </li>
            {% endfor %}
            </ul>
            {% endif %}
        </li>
    {% endif %}
{% endfor %}
</ul>

범주 계층 수준이 두 개 이상이면 어떻게됩니까?
pmoubed
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.