Twig'de bir ağaç nasıl oluşturulur


90

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:


117

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>

9
Çok iyi teşekkürler! Makroyu aynı şablonda kullanmak isterseniz kullanabilirsiniz {{ _self.menu_links(links) }}.
grip

teşekkür ederim, bunun düşüncesi beynimi incitti ama cevabın çok mantıklı.
azzy81

Projemle ilgili yorumlarla ilgili bir sorun yaşadım. alt yorumlar (alt bağlantılar) da ana koleksiyona (bağlantılar) dahil edildi. bu yüzden eklemeden önce yorumun bir 'ebeveyn' girişi olup olmadığını kontrol etmem gerekiyordu.
Jevgeni Smirnov

4
Kullanılması {{_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
dr.scre

37

Dal 2.0 - 2.11

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-coderyanı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

Dal> = 2.11

İtibariyle Twig 2.11 , sen atlayabilirsiniz {% import _self as macros %}satır içine makrolar altında otomatik olarak alınır gibi _selfad (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>

2

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

1
Ek değişkenleri aktaramazsınız 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.
chx

1

İ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 !


1

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

-1

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>

Birden fazla kategori hiyerarşiniz varsa ne olur?
pmoubed
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.