loops recursive - Как сделать дерево в Twig




macro symfony (6)

Я хотел бы сделать дерево с неопределенной глубиной (дети детей детей и т. Д.). Мне нужно петлю через массив рекурсивно; как я могу это сделать в Twig?


Answers

Спасибо 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 %}

Затем в главном шаблоне назовите это (вид избыточности «с« там »):

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

Надеюсь, поможет :)


Если вы используете PHP 5.4 или новее, есть замечательное новое решение (по состоянию на май 2016 года) по этой проблеме Алена Тимбло: https://github.com/ninsuo/jordan-tree .

Это тег «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 %}

Сначала я подумал, что это можно решить просто, но это не так просто.

Вам нужно создать логику, возможно, с помощью метода класса 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 , которая доступна внутри цикла twig for . Но я не уверен в объеме этой переменной цикла .

Извините за предоставление только подхода не решение, но, возможно, я надеюсь, что мои мысли могут помочь вам (немного).

Эта и другая информация доступна на Twigs «for» Docu !


Ответы здесь приводят мое решение.

У меня есть объект категории с самостоятельной привязкой к ассоциации ManyToOne (родительский к детям).

/**
 * @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>

Если вы хотите использовать макрос в том же шаблоне, вы должны использовать что-то вроде этого, чтобы оставаться совместимым с 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 и включает dr.scre к macro чтобы теперь использовать _self но импортировать локально.


Я нашел ответ:

{% for key,value in array_path %}
    Key : {{ key }}
    Value : {{ value }}
{% endfor %}




loops recursion tree twig