loops - Cómo renderizar un árbol en Twig
recursion tree (6)
Me gustaría renderizar un árbol con una profundidad indeterminada (hijos de hijos de niños, etc.). Necesito recorrer el conjunto recursivamente; ¿Cómo puedo hacer esto en Twig?
Gracias domi27, jugué con tu idea y se me ocurrió esto. Hice una matriz anidada ya que mi árbol, [''link''] [''sublinks''] es nulo u otra matriz de más de lo mismo.
Plantillas
El archivo de la sub-plantilla para recurse con:
<!--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 %}
Luego, en la plantilla principal, llame a esto (un poco redundante ''con'' cosas allí):
<ul class="main-menu">
{% include "includes/menu-links.html" with {''links'':links} only %}
</ul>
Macros
Un efecto similar se puede lograr con macros:
<!--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 %}
En la plantilla principal, haga esto:
{% import "macros/menu-macros.html" as macros %}
<ul class="main-menu">
{{ macros.menu_links(links) }}
</ul>
Espero eso ayude :)
Las respuestas aquí me llevan a mi Solución.
Tengo una Entidad de categoría con autorreferenciación de la asociación ManyToOne (de padres a hijos).
/**
* @ORM/ManyToOne(targetEntity="Category", inversedBy="children")
*/
private $parent;
/**
* @ORM/OneToMany(targetEntity="Category", mappedBy="parent")
*/
private $children;
En mi plantilla twig estoy renderizando la vista de árbol así:
<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>
Primero pensé que esto podría resolverse de manera directa, pero no es tan fácil.
Necesita crear una lógica, tal vez con un método de clase php, cuándo incluir una subpestaña twig y cuándo no.
<!-- 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>
De modo que podría usar la variable especial de bucle de ramita , que está disponible dentro de un ramal para bucle . Pero no estoy seguro del alcance de esta variable de bucle .
Perdón por proporcionar solo un enfoque, no una solución, pero quizás espero que mis pensamientos puedan ayudarlo (un poco).
Esta y otras informaciones están disponibles en Twigs "for" Docu !
Si desea utilizar una macro en la misma plantilla , debe usar algo como esto para mantenerse compatible con 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>
Esto amplía la respuesta del random-coder
e incorpora la dr.scre
de dr.scre
a la macro que ahora se usan, pero que se importan localmente.
Si está ejecutando PHP 5.4 o superior, hay una nueva y maravillosa solución (a partir de mayo de 2016) para este problema de Alain Tiemblo: https://github.com/ninsuo/jordan-tree .
Es una etiqueta de "árbol" que sirve para este propósito exacto. El marcado se vería así:
{% 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 %}
Tomó la respuesta de la gripe y la modificó un poco:
{# 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) }}