检查数组中是否有任何项目具有特定值

Check if any item has certain value in an Array

我试着得到一个像这样的html结构

<h2>Next</h2>
<article> First Entry </article>
<article> Second Entry </article>
....
<h2>Previous</h2>
<article> First Entry </article>
<article> Second Entry </article>
...

所以我用

检查日期
{% for event in events %}
{%- if date(event.band_date) | date('Y-m-d') > 'now' | date('Y-m-d') -%}
Next Stuff
{% endif %}
{% endfor %}

{% for event in events %}
{%- if date(event.band_date) | date('Y-m-d') < 'now' | date('Y-m-d') -%}
Previous Stuff
{% endif %}
{% endfor %}

现在我想弄清楚如何在不进入循环的情况下将 h2 放入其中并复制自身,另外如果日期范围内没有条目根本不显示。

<h2> 放在循环之外,它只会显示一次 header。

<h2>Next</h2>
{% for event in events %}
    {%- if date(event.band_date) | date('Y-m-d') > 'now' | date('Y-m-d') -%}
        stuff
    {% endif %}
{% endfor %}

<h2>Previous</h2>
{% for event in events %}
    {%- if date(event.band_date) | date('Y-m-d') < 'now' | date('Y-m-d') -%}
        stuff
    {% endif %}
{% endfor %}

好的,我知道了! loop.first 成功了!

{% for event in events %}
    {%- if date(event.band_date) | date('Y-m-d') > 'now' | date('Y-m-d') -%}
      {% if loop.first %}
        <h2>Next</h2>
      {% endif %}
      ...
    {% endif %}
{% endfor %}

一个丑陋的解决方案是使用变量来跟踪是否已输出标题:

{% set heading_outputted = false %}
{% for event in events %}
  {% if date(event.band_date)|date('Y-m-d') > 'now'|date('Y-m-d') %}
    {% if not heading_outputted %}
      <h2>Next</h2>
      {% set heading_outputted = true %}
    {% endif %}

    <article>
      {{ event.band }} - {{ event.band_date|date('Y-m-d') }}
    </article>
  {% endif %}
{% endfor %}

{% set heading_outputted = false %}
{% for event in events %}
  {% if date(event.band_date)|date('Y-m-d') < 'now'|date('Y-m-d') %}
    {% if not heading_outputted %}
      <h2>Previous</h2>
      {% set heading_outputted = true %}
    {% endif %}

    <article>
      {{ event.band }} - {{ event.band_date|date('Y-m-d') }}
    </article>
  {% endif %}
{% endfor %}

示例:https://twigfiddle.com/0kdp0u


更好的解决方案是将逻辑放在 PHP 中,例如在控制器中,或者项目中任何可能最合适的位置。如果将变量 next_eventsprevious_events 传递给 Twig,视图会更清晰:

{% if next_events is not empty %}
  <h2>Next</h2>
  {% for event in next_events %}
    <article>
      {{ event.band }} - {{ event.band_date|date('Y-m-d') }}
    </article>
  {% endfor %}
{% endif %}

{% if previous_events is not empty %}
  <h2>Previous</h2>
  {% for event in previous_events %}
    <article>
      {{ event.band }} - {{ event.band_date|date('Y-m-d') }}
    </article>
  {% endfor %}
{% endif %}

示例:https://twigfiddle.com/cvka3g


使用 filter filter and the loop variable 的另一种解决方案:

{% for event in events|filter(event => date(event.band_date)|date('Y-m-d') > 'now'|date('Y-m-d')) %}
  {% if loop.first %}
    <h2>Next</h2>
  {% endif %}

  <article>
    {{ event.band }} - {{ event.band_date|date('Y-m-d') }}
  </article>
{% endfor %}

{% for event in events|filter(event => date(event.band_date)|date('Y-m-d') < 'now'|date('Y-m-d')) %}
  {% if loop.first %}
    <h2>Previous</h2>
  {% endif %}

  <article>
    {{ event.band }} - {{ event.band_date|date('Y-m-d') }}
  </article>
{% endfor %}

(此方案灵感来自@Seba 的回答。)

出于安全原因,Twigfiddle 已禁用 filter 过滤器,因此此解决方案没有可运行的示例。

请注意,以下语法在 Twig 3 中不起作用:

{% for event in events if date(event.band_date)|date('Y-m-d') > 'now'|date('Y-m-d') %}
  {% if loop.first %}
    <h2>Next</h2>
  {% endif %}

  <article>
    {{ event.band }} - {{ event.band_date|date('Y-m-d') }}
  </article>
{% endfor %}

它在 Twig 2 中确实有效(示例:https://twigfiddle.com/zau2sf),但您会收到以下弃用通知:

Using an "if" condition on "for" tag in "main.twig" at line 1 is deprecated since Twig 2.10.0, use a "filter" filter or an "if" condition inside the "for" body instead (if your condition depends on a variable updated inside the loop).


我个人会选择第二种解决方案,因为 Twig 模板最清晰。如果那不可能,我会选择第三种解决方案。第一个解决方案太乱了,我不会选择它。