it-swarm.com.de

Wie man einen Baum in Twig rendert

Ich möchte einen Baum mit einer unbestimmten Tiefe darstellen (Kinder von Kindern von Kindern usw.). Ich muss das Array rekursiv durchlaufen. Wie kann ich das in Twig machen?

86
T-RonX

Danke, domi27, ich habe mit deiner Idee herumgespielt und mir das ausgedacht. Ich habe ein verschachteltes Array als Baum erstellt. ['Link'] ['sublinks'] ist null oder ein anderes Array davon.

Vorlagen

Die untergeordnete Vorlagendatei, die wiederhergestellt werden soll:

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

Dann rufen Sie in der Hauptvorlage Folgendes auf (etwas überflüssiges "mit" dort):

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

Makros

Ein ähnlicher Effekt kann mit Makros erzielt werden:

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

In der Hauptvorlage tun Sie dies:

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

Ich hoffe es hilft :)

104

Wenn Sie ein Macro in derselben Vorlage verwenden möchten, sollten Sie Folgendes verwenden, um kompatibel zu Twig 2.x zu bleiben:

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

Dies erweitert die Antwort von random-coder und enthält den Hinweis von dr.scre zur twig-Dokumentation zu Makros , um jetzt _self zu verwenden, aber lokal zu importieren.

29
flu

Zuerst dachte ich, das könnte einfach gelöst werden - aber so einfach ist es nicht.

Sie müssen eine Logik erstellen, möglicherweise mit einer PHP-Klassenmethode, wann eine Zweigvorlage eingefügt werden soll und wann nicht.

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

Sie können also die spezielle twig-Schleifenvariable verwenden, die in einem Zweig for-Schleife verfügbar ist. Ich bin mir jedoch nicht sicher, in welchem ​​Umfang diese loop - Variable liegt.

Entschuldigen Sie bitte, dass Sie nur einen Ansatz und keine Lösung anbieten, aber vielleicht hoffe ich, dass Ihnen meine Gedanken (ein wenig) helfen können.

Diese und weitere Informationen finden Sie auf Twigs "für" Docu !

2
domi27

Wenn Sie PHP 5.4 oder höher verwenden, gibt es eine wunderbare neue Lösung (Stand Mai 2016) für dieses Problem von Alain Tiemblo: https://github.com/ninsuo/jordan-tree

Es ist ein "Baum" -Tag, der genau diesem Zweck dient. Markup würde so aussehen:

{% 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 %}
2
Jordan Lev

Antwortete die Grippe und modifizierte sie ein wenig:

{# 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) }}
0

Die Antworten hier führen mich zu meiner Lösung.

Ich habe eine Kategorie-Entität mit selbstreferenzierender ManyToOne-Zuordnung (Elternteil an Kinder).

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

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

In meiner Zweigvorlage rendere ich die Baumansicht folgendermaßen:

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