【问题标题】:Check if any item has certain value in an Array检查任何项目是否在数组中具有特定值
【发布时间】:2020-08-21 16:46:45
【问题描述】:

我尝试得到这样的 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,而不是在循环中并复制自身,以及如果在日期范围内没有条目根本不显示。

【问题讨论】:

  • 您介意在您的代码中添加{% endif %}{% endfor %} 结束标签以获得更高的特异性吗?
  • 当然,我编辑了帖子

标签: twig timber


【解决方案1】:

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

{% 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 filterloop 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),但您会收到以下弃用通知:

自 Twig 2.10.0 起,不推荐在第 1 行的“main.twig”中的“for”标签上使用“if”条件,而是在“for”正文中使用“filter”过滤器或“if”条件(如果您的条件取决于循环内更新的变量)。


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

【讨论】:

    【解决方案2】:

    &lt;h2&gt; 放在循环之外,它只会作为标题显示一次。

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

    【讨论】:

    • 是的,但我想先检查一下,是否有符合这些条件的事件,否则它不应该显示“下一个”或“上一个”
    【解决方案3】:

    好的,我明白了! 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 %}
    

    【讨论】:

    • 如果这对您有用,则意味着events 数组中的第一个事件属于“下一个”部分,而代码不适用于“上一个”部分。示例:twigfiddle.com/bxrk3b
    • 是的,你是对的。它现在对我有用,如果我像 {% for event in events if date(event.band_date) | date('Y-m-d') &gt; 'now' | date('Y-m-d') %} 一样将 if 语句放在循环本身中,但不知何故在小提琴中出现语法错误?!
    • 您使用的是 Twig 2 吗?我用更彻底的回复更新了我的答案。
    • 刚刚发现 Timber 使用的是 1.42.5 版本,可以通过 composer 更新它,大概会这样做,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 2019-11-15
    • 2020-10-01
    相关资源
    最近更新 更多