【问题标题】:How to render a tree in Twig如何在 Twig 中渲染一棵树
【发布时间】:2011-11-30 13:10:32
【问题描述】:

我想渲染一棵深度不确定的树(children of children 等)。我需要递归地遍历数组;我如何在 Twig 中做到这一点?

【问题讨论】:

    标签: loops recursion tree twig


    【解决方案1】:

    我玩弄了domi27's idea 并想出了这个。我做了一个嵌套数组作为我的树,['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 %}
    

    然后在主模板中,调用它(那里有一些多余的'with'东西):

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

    【讨论】:

    • 很好,谢谢!如果你想在同一个模板中使用宏,你可以使用{{ _self.menu_links(links) }}
    • 谢谢你,想到这个让我很头疼,但你的回答很有道理。
    • 我的项目与 cmets 有一个问题。 subcmets(子链接)也包含在主集合(链接)中。所以在包含之前,我必须检查评论是否有“父”条目。
    • 使用{{_self.menu_links}} 是一种不好的做法!在此处阅读注释:macro 当您在要使用它的模板中定义宏时,您可能会想通过 _self.input() 直接调用该宏,而不是导入它;即使看起来可行,这也只是当前实现的副作用,它在 Twig 2.x 中不再有效。您应该再次在本地导入宏在menu_links
    【解决方案2】:

    树枝 2.0 - 2.11

    如果你想在同一个模板中使用,你应该使用类似这样的东西来保持与 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 的提示合并到Twig documentation about macros 现在使用_self,但在本地导入。

    树枝 >= 2.11

    Twig 2.11 开始,您可以省略 {% import _self as macros %},因为内联宏会在 _self 命名空间下自动导入(请参阅 Twig announcement: Automatic macro import):

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

    【讨论】:

      【解决方案3】:

      如果您运行的是 PHP 5.4 或更高版本,Alain Tiemblo 为这个问题提供了一个很棒的新解决方案(截至 2016 年 5 月):https://github.com/ninsuo/jordan-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 %}
      

      【讨论】:

      • 您不能将其他变量传递给subtree。在我的情况下,代码需要知道是否会有更多的孩子,并将级别数传递给宏,以便它可以执行&lt;div class="{{ classes[current_level].wrapper }} {% if levels &gt; current_level %}accordion-wrapper{% endif %}"&gt;。计算这个需要第二次迭代当前关卡来捕捉是否有任何孩子。
      【解决方案4】:

      首先我认为这可能会以一种简单的方式解决,但并不是那么容易。

      您需要创建逻辑,可能使用 PHP 类方法,何时包含 Twig 子模板,何时不包含。

      <!-- 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 loop variable,它在 Twig for 循环中可用。但我不确定这个 loop 变量的范围。

      此信息和其他信息可在 Twigs "for" Docu! 上获得!

      【讨论】:

        【解决方案5】:

        flu's answer并稍作修改:

        {# 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】:

          这里的答案引导我找到我的解决方案。

          我有一个具有自引用多对一关联(父对子)的类别实体。

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

          【讨论】:

          • 如果您有多个类别层次结构怎么办?
          猜你喜欢
          • 1970-01-01
          • 2016-05-19
          • 2023-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-01
          • 2010-09-06
          相关资源
          最近更新 更多