Me gustaría renderizar un árbol con una profundidad indeterminada (hijos de hijos de hijos, etc.). Necesito recorrer la matriz de forma recursiva; ¿Cómo puedo hacer esto en Twig?
89
Jugué con la idea de domi27 y se me ocurrió esto. Hice una matriz anidada como mi árbol, ['enlace'] ['subvínculos'] es nulo u otra matriz de más de lo mismo.
Plantillas
El archivo de sub-plantilla para recurrir 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 (tipo de cosas redundantes 'con' allí):
<ul class="main-menu">
{% include "includes/menu-links.html" with {'links':links} only %}
</ul>
Macros
Se puede lograr un efecto similar 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, haz esto:
{% import "macros/menu-macros.html" as macros %}
<ul class="main-menu">
{{ macros.menu_links(links) }}
</ul>
{{ _self.menu_links(links) }}
.{{_self.menu_links}}
es una mala práctica ! Lea una nota aquí: macro Cuando define una macro en la plantilla donde la va a usar, puede tener la tentación de llamarla directamente a través de _self.input () en lugar de importarla; incluso si parece funcionar, esto es solo un efecto secundario de la implementación actual y ya no funcionará en Twig 2.x. Debería importar macros localmente una vez másmenu_links
Ramita 2.0 - 2.11
Si desea usar una macro en la misma plantilla , debe usar algo como esto para seguir siendo compatible con Twig 2.x :
Esto amplía
random-coder
la respuesta e incorporadr.scre
una pista a la documentación de Twig sobre macros para usar ahora_self
, pero importar localmente.Ramita> = 2,11
A partir de Twig 2.11 , puede omitir
{% import _self as macros %}
, ya que las macros en línea se importan automáticamente en el_self
espacio de nombres (consulte Anuncio de Twig: Importación automática de macros ):fuente
Si está ejecutando PHP 5.4 o superior, existe 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 exactamente para este propósito. El marcado se vería así:
fuente
subtree
. En mi caso, el código necesita saber si habrá más hijos y pasa el número de niveles a la macro para que pueda hacer un<div class="{{ classes[current_level].wrapper }} {% if levels > current_level %}accordion-wrapper{% endif %}">
. Calcular esto requeriría iterar el nivel actual por segunda vez solo para capturar si hay hijos.Primero pensé que esto podría resolverse de una manera sencilla, pero no es tan fácil.
Necesita crear lógica, tal vez con un método de clase PHP, cuándo incluir una subplantilla Twig y cuándo no.
Por lo tanto, podría usar la variable de bucle especial Twig , que está disponible dentro de un bucle Twig for . Pero no estoy seguro del alcance de esta variable de ciclo .
Esta y otra información están disponibles en Twigs "para" Docu !
fuente
Tomó la respuesta de la gripe y la modificó un poco:
fuente
Las respuestas aquí me llevan a mi solución.
Tengo una entidad de categoría con una asociación de varios a uno que hace referencia a sí misma (de padres a hijos).
En mi plantilla Twig, estoy representando la vista de árbol de esta manera:
fuente