Belirsiz derinliğe sahip bir ağaç yapmak istiyorum (çocukların çocuklarının çocukları vb.). Dizide özyinelemeli döngü yapmam gerekiyor; bunu Twig'de nasıl yapabilirim?
Yanıtlar:
Ben etrafında oynanan domi27 fikri . Ağacım olarak iç içe geçmiş bir dizi yaptım, ['link'] ['sublinks'] null veya aynı diziden daha fazlası.
Şablonlar
Aşağıdakilerle tekrarlanacak alt şablon dosyası:
<!--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 %}
Daha sonra ana şablonda şunu arayın (bir tür fazlalık 'ile' orada şeyler):
<ul class="main-menu">
{% include "includes/menu-links.html" with {'links':links} only %}
</ul>
Makrolar
Makrolarla da benzer bir etki elde edilebilir:
<!--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 %}
Ana şablonda şunu yapın:
{% import "macros/menu-macros.html" as macros %}
<ul class="main-menu">
{{ macros.menu_links(links) }}
</ul>
{{_self.menu_links}}
bir olduğunu kötü bir uygulamadır ! Burada bir not okuyun: makro Kullanacağınız şablonda bir makro tanımladığınızda, makroyu içe aktarmak yerine doğrudan _self.input () aracılığıyla çağırmak isteyebilirsiniz; işe yarıyor gibi görünse bile, bu sadece mevcut uygulamanın bir yan etkisidir ve artık Twig 2.x'te çalışmayacaktır. Makroları bir kez daha yerel olarak içe aktarmalısınız insitemenu_links
Aynı şablonda bir makro kullanmak istiyorsanız , Twig 2.x ile uyumlu kalmak için şuna benzer bir şey kullanmalısınız :
{% 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>
Bu, random-coder
yanıtını genişletir ve Twig belgelerine şu anda kullanılacak , ancak yerel olarak içe aktarılacak makrolarla ilgilidr.scre
ipucunu birleştirir ._self
İtibariyle Twig 2.11 , sen atlayabilirsiniz {% import _self as macros %}
satır içine makrolar altında otomatik olarak alınır gibi _self
ad (bkz Twig duyuru: Otomatik makro ithalat ):
{# {% import _self as macros %} - Can be removed #}
<ul class="main-menu">
{{ _self.menu_links(links) }} {# Use _self for inlined macros #}
</ul>
PHP 5.4 veya üstünü çalıştırıyorsanız, bu soruna Alain Tiemblo tarafından (Mayıs 2016 itibariyle) harika bir yeni çözüm var: https://github.com/ninsuo/jordan-tree .
Tam olarak bu amaca hizmet eden bir "ağaç" etiketidir. Biçimlendirme şöyle görünecektir:
{% 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
. Benim durumumda, kodun daha fazla çocuk olup olmayacağını bilmesi gerekiyor ve bir <div class="{{ classes[current_level].wrapper }} {% if levels > current_level %}accordion-wrapper{% endif %}">
. Bunu hesaplamak, sadece herhangi bir çocuk olup olmadığını yakalamak için mevcut seviyeyi ikinci kez yinelemeyi gerektirir.
İlk önce bunun basit bir şekilde çözülebileceğini düşündüm, ama bu o kadar kolay değil.
Bir Twig alt şablonunu ne zaman dahil edeceğiniz ve ne zaman eklemeyeceğiniz bir PHP sınıf yöntemi ile mantık oluşturmanız gerekir.
<!-- 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>
Böylece Twig for döngüsü içinde bulunan özel Twig döngü değişkenini kullanabilirsiniz . Ama bunun kapsamından emin değilim döngü değişkeninin .
Bu ve diğer bilgiler Twigs'de "Docu !
Grip cevabını aldı ve biraz değiştirdi:
{# 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) }}
Buradaki cevaplar beni çözümüme götürüyor.
Kendi kendine referans veren çoktan bire ilişkiye sahip bir kategori varlığım var (ebeveynden çocuklara).
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
private $children;
Twig şablonumda ağaç görünümünü şu şekilde oluşturuyorum:
<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) }}
.