【问题标题】:Twig, add first and last classTwig,添加第一个和最后一个类
【发布时间】:2011-12-11 20:32:46
【问题描述】:

假设我有一个这样的 for 循环:

{% for elem in arrMenu %}
    <div class="topmenu-button">
        <a href="{{ elem.url }}">{{ elem.name }}</a>
    </div>
{% endfor %}

在这种形式下,它会呈现如下内容:

<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>

twig 如何帮助我在 div 中添加第一个和最后一个类,以便我得到如下结果:

<div class="topmenu-button first"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button last"><a href="url">name</a></div>

【问题讨论】:

  • 您可以使用 :first-child:last-child 伪类。这些天来,这些都得到了广泛的支持。
  • 您也可以使用IE7-js 为某些旧版IE 添加对CSS3 的支持。
  • 只是一个简短的说明;我刚刚纠正了一个错误,我反转了 for 参数。

标签: php symfony twig


【解决方案1】:

您可以根据需要使用“特殊变量”loop.firstloop.last

LINK

{% for elem in arrMenu %}
    {% if loop.first %}
    <div class="topmenu-button first">        
    {% elseif loop.last %}
    <div class="topmenu-button last">        
    {% else %}
    <div class="topmenu-button">        
    {% endif %}
        <a href="{{ elem.url }}">{{ elem.name }}</a>
    </div>
{% endfor %}

编辑:根据您对“一个案例”的关心程度,您可能需要这样的解决方案。

{% for elem in arrMenu %}
    {% set classes = ["topmenu-button"] %}
    {% if loop.first %}{% set classes = classes|merge(["first"]) %}{% endif %}
    {% if loop.last %}{% set classes = classes|merge(["last"]) %}{% endif %}
    <div class="{{ classes|join(" ") }}">        
        <a href="{{ elem.url }}">{{ elem.name }}</a>
    </div>
{% endfor %}

【讨论】:

  • 也许我错了,我对 Twig 还很陌生,但如果数组只包含一个元素,if 语句将同时执行,从而导致 class="topmenu-button first last。在这种情况下,您应该使用if...else。但正如我所说,我可能错了。
【解决方案2】:

由于循环不能同时是firstlast,我宁愿不使用elseif 并编写(DRY - 如果您将来必须更改topmenu-button 怎么办?):

{% for elem in arrMenu %}
    {% set append %}
        {% if loop.first %}first{% endif %}
        {% if loop.last %}last{% endif %}
    {% endset %}
    <div class="topmenu-button {{ append }}">
        <a href="{{ elem.url }}">{{ elem.name }}</a>
    </div>
{% endfor %}

或更简洁:

{% for elem in arrMenu %}
    <div class="topmenu-button {% if loop.first %}first{% endif %} {% if loop.last %}last{% endif %}">
        <a href="{{ elem.url }}">{{ elem.name }}</a>
    </div>
{% endfor %}

编辑:这样您将在class 属性中获得一些额外的空格(顺便说一句,这很好)。 Edit2:这不会处理 1 元素数组(第一个 = 最后一个)

【讨论】:

  • 我曾经尝试像这样编写 HTML(和 twig),但老实说,您的“更简洁”解决方案看起来更嘈杂,并且前面的示例设置变量的代码比&lt;div&gt;您的打印主体。像 TWIG 这样诱人的语言并不适合完全符合 DRY,因为所有“代码”都必须通过 {%/%} 转义。
  • @KendallHopkins 我同意你所说的简洁代码,我将永远使用第一个。恕我直言,最好编写更多代码来设置变量,而不是重复 div 声明和 class 属性 3 次。像你这样重复大量的东西,改变一些东西真的很痛苦(而且浪费时间和金钱)。加上elseifelse 对我来说看起来很可怕。
  • 再看这个问题,我觉得我们都错了。我们忘记了“一个”案例,您可以在其中拥有class="topmenu-button first last"。鉴于增加的复杂性,我认为我最好由merge 过滤器处理并将其分解为类似于您的操作方式的自己的变量。我已经更新了我的答案,WDYT?
  • @KendallHopkins 你说得对。为您+1,我喜欢您在编辑中的(第二种)方法。但是我会反转 loop.firstloop-last 检查,因为数组的第一个也是唯一一个元素应该被考虑和设置为第一个元素。但这取决于他。
【解决方案3】:

如果是管理标签的类属性,三元条件会更好。

<span class="topmenu-button {{ (loop.first) ? 'first' : '' }}">{{ item.text }}</span>

【讨论】:

    【解决方案4】:

    我在 Drupal 8 视图模板中使用它。感谢“elseif”,如果您只有一项,那么第一项永远不会获得“最后”类:

    {% for row in rows %}
        {% set parity = cycle(['odd', 'even'], loop.index0) %}
        {% set row_classes = [ default_row_class ? 'views-row', ] %}    
    
        <div class="views-prerow {{parity}}{% if loop.first %} first{% elseif loop.last %} last{% endif %}">
            <div{{ row.attributes.addClass(row_classes) }}>
                {{ row.content }}
            </div>
        </div>
    {% endfor %}
    

    【讨论】:

      猜你喜欢
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-08
      • 2016-12-31
      • 2021-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多