Cómo hacer un árbol en Rama

Me gustaría hacer un árbol con un indeterminado de profundidad (los hijos de los hijos de los hijos, etc.). Necesito un bucle a través de la matriz de forma recursiva; ¿cómo puedo hacer esto en Twig?

InformationsquelleAutor T-RonX | 2011-11-30

6 Kommentare

  1. 112

    He jugado con domi27 la idea y me encontré con esto. Hice una matriz anidada como mi árbol, [‘link’][‘sublinks’] es nulo o con una variedad de más de lo mismo.

    Plantillas

    La sub-archivo de 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 %}
    

    A continuación, en la plantilla principal, llame a este (tipo de redundante ‘con’ cosas):

    <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, hacer esto:

    {% import "macros/menu-macros.html" as macros %}
    <ul class="main-menu">
        {{ macros.menu_links(links) }}
    </ul>
    
    • Muy bueno, gracias! Si desea utilizar la macro en la misma plantilla que se puede utilizar {{ _self.menu_links(links) }}.
    • gracias, este pensamiento hizo que mi cerebro herido, pero su respuesta hace perfecto sentido.
    • Tuve un problema con mi proyecto con los comentarios. subcomments(sublinks) también fueron incluidos en la colección principal(enlaces). así que antes de incluir tuve que comprobar si el comentario tuvo un ‘padre’ de la entrada.
    • El uso de {{_self.menu_links}} es un malas prácticas! Leer una nota aquí: macro Al definir una macro en la plantilla donde se va a usar, usted podría estar tentado a llamar a la macro directamente a través de _self.de entrada() en lugar de importación; incluso si parece que funciona, esto es sólo un efecto secundario de la aplicación actual y no va a funcionar más en Rama 2.x. Usted debe importar macros localmente una vez más insite menu_links
  2. 35

    Rama 2.0 – 2.11

    Si desea utilizar un macro en la misma plantilla, usted debe usar algo como esto para permanecer compatible con la Ramita de 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 se extiende random-coder‘s respuesta e incorpora dr.scre‘s ayuda a la La ramita de la documentación acerca de las macros para usar ahora _self, pero la importación localmente.

    Ramita >= 2.11

    Como de Ramita 2.11, se puede omitir el {% import _self as macros %}, como entre líneas macros se importan automáticamente en el _self espacio de nombres (ver Ramita anuncio: macro Automática de importación):

    {# {% import _self as macros %} - Can be removed #}
    
    <ul class="main-menu">
        {{ _self.menu_links(links) }} {# Use _self for inlined macros #}
    </ul>
    
  3. 2

    Si está ejecutando PHP 5.4 o superior, hay una maravillosa nueva solución (a partir de Mayo de 2016) a este problema por Alain Tiemblo: https://github.com/ninsuo/jordan-tree.

    Es un «árbol» de la etiqueta que sirve para este propósito exacto. Marcado tendría este aspecto:

    {% 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 %}
    
    • No se puede pasar variables adicionales a subtree. En mi caso, el código necesita saber si habrá más niños y se pasa el número de niveles de la macro de modo que puede hacer un <div class="{{ classes[current_level].wrapper }} {% if levels > current_level %}accordion-wrapper{% endif %}">. El cálculo de este requeriría recorrer el actual nivel de un segundo tiempo sólo para capturar si hay niños.
  4. 1

    Principio pensé que esto podría ser resuelto de una manera directa, pero no es tan fácil.

    Usted necesita para crear la lógica, tal vez con una clase de PHP método, al incluir una Ramita subtemplate y cuando 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>
    

    Así que usted podría utilizar el especial La ramita de la variable de bucle, que está disponible en el interior de una Ramita bucle for. Pero no estoy seguro acerca del alcance de esta bucle variable.

    Esta y otra información están disponibles en Ramitas «para» Docu!

  5. 0

    Tomó la respuesta de la gripe y modificado 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) }}
    
  6. -1

    Las respuestas aquí guiar a mi a mi solución.

    Tengo una categoría de entidad con una auto-referencia de muchos-a-uno (asociación 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 de representación en la vista de árbol como este:

    <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>
    
    • ¿Qué pasa si usted tiene más de un nivel de la jerarquía de categorías?

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea