因为drupal的in-twitch模板的行为很奇怪



我试图只显示事件列表中即将发生的事件。以下是我试图展示的内容。

<div class="row">
    {% for item in items %}
        {% if item.content['#node'].field_event_type.getValue()|first.value == 'upcoming' %}
            <div class="col">{{item.content}}</div>
        {% endif %}
    {% endfor %}
</div>

但是输出呈现是,第二个事件显示在div行之后,如下所示。我不明白这是怎么发生的,因为for循环在div 行中

<div class="row"> 
  <div class="col"> content </div>
</div><div class="col"> content </div>

预期输出

<div class="row"> 
  <div class="col"> content </div>
  <div class="col"> content </div>
</div>

Twig做了很多事情:

  • 加载(打开你的Twig内容)
  • 解析(从Twig内容创建解析树)
  • 编译(浏览该树以创建php文件)
  • 缓存(将php文件存储在某个位置,以避免下次重新编译)
  • 执行(执行生成的php文件)

当在解析过程中检测到{% for %}时,Twig递归调用令牌解析器,直到找到{% endfor %}并构建令牌树。在您的情况下,它看起来像:

root
 |
 --- string
 |
 --- for
 |   |
 |    --- if
 |        |
 |        --- string
 |
 --- string

然后,Twig编译器递归地遍历该树并生成相应的php代码。这样,下面的Twig循环:

{% for i in 1..5 %}
Value = {{ i }}
{% endfor %}

在PHP中编译为:

// line 1
$context['_parent'] = $context;
$context['_seq'] = twig_ensure_traversable(range(1, 5));
foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
    // line 2
    echo "Value = ";
    echo twig_escape_filter($this->env, $context["i"], "html", null, true);
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_iterated'], $context['_key'], $context['i'], $context['_parent'], $context['loop']);
$context = array_intersect_key($context, $_parent) + $_parent;

正如您所看到的,{% for %}只不过是一个简单的foreach,由于Twig令牌存储在树中,因此在设计上不可能显示位于一对打开/关闭标签下方的内容。

我能看到的唯一可能性是,你在Twig中使用的一个标签正在玩输出缓冲,而你在循环中使用的其中一个方法破坏了ob堆栈(例如,没有任何ob_start()ob_get_clean(),以前已经打开过)。

我的建议是将你的trick文件名grep到你的缓存目录中(例如:grep -Ri 'test.twig' cache/),以便查看该文件被编译成PHP,确切地了解它的作用,并对其进行调试。

不要在trick中过滤内容,而是在Drupal视图中过滤结果。

在视图的"筛选条件"中,选择field_event_type字段并将其设置为"等于",然后选择/添加"即将到来"作为选项。

如果在视图中进行过滤,则不必处理树枝模板。

最新更新