깊이가 결정되지 않은 나무를 렌더링하고 싶습니다 (자녀의 자식 등). 배열을 재귀 적으로 반복해야합니다. Twig에서 어떻게 할 수 있습니까?
답변:
나는 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>
{{_self.menu_links}}
은 나쁜 습관입니다 ! 여기에서 메모를 읽으십시오. macro 매크로 를 사용할 템플릿에 매크로를 정의 할 때 매크로를 가져 오는 대신 _self.input ()을 통해 직접 호출하고 싶을 수 있습니다. 작동하는 것처럼 보이지만 이는 현재 구현의 부작용 일 뿐이며 Twig 2.x에서는 더 이상 작동하지 않습니다. 매크로를 다시 한 번 사이트 내에서 로컬로 가져와야합니다menu_links
동일한 템플릿에서 매크로 를 사용하려면 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 , 당신은 생략 할 수 {% 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>
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 %}
subtree
. 필자의 경우 코드는 더 많은 자식이 있을지 여부를 알아야하며 레벨 수를 매크로에 전달하여 <div class="{{ classes[current_level].wrapper }} {% if levels > current_level %}accordion-wrapper{% endif %}">
. 이를 계산하려면 자식이 있는지 여부를 캡처하기 위해 현재 수준을 두 번 반복해야합니다.
처음에는 이것이 간단한 방법으로 해결 될 수 있다고 생각했지만 그렇게 쉽지는 않습니다.
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 에서 확인할 수 있습니다 !
툭 독감의 답변을 하고 그것을 조금 수정 :
{# 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) }}
여기에 대한 대답은 내 솔루션으로 이어집니다.
자체 참조 다 대일 연결 (자녀의 부모)이있는 범주 엔터티가 있습니다.
/**
* @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>
{{ _self.menu_links(links) }}
.