Twig:如何检查字段的内部 html 内容

Twig: how to check the inner html content of a field

我有一个字段,该字段可以有一行或两行 html:

<p>One line</p>

或:

<p>first line</p>
<p>Second line </p>

如何使用 twig 检查该字段是否有一个或两个

标签。

我想做的事的例子:

{% if item|length('<p>') = 1 %}
     <div class="one">{{ item }}</div>
 {% elseif item|length('<p>') = 2 %}
     <div class="two">{{ item }}</div>
 {% endif %}

关于如何实现这个的任何想法?

更新#1:Honza 说的是真的我希望父项 div 有一个 class 如果项目中只有一行,另一个 class 如果有项目中有两行

更新 #2 这是我的树枝文件中的实际标记。

{%
  set classes = [
    'field',
    'field--name-' ~ field_name|clean_class,
    'field--type-' ~ field_type|clean_class,
    'field--label-' ~ label_display,
  ]
%}
{%
  set title_classes = [
    'field__label',
    label_display == 'visually_hidden' ? 'visually-hidden',
  ]
%}

  <div{{ attributes.addClass(classes) }}>

    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>

    {% if multiple %}  <div class="field__items"> {% endif %}

    {% for item in items %}
      <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
    {% endfor %}

    {% if multiple %} </div> {% endif %}
  </div>

我希望 field__item 有一个 class 当它有一个 <p> 标签时有一个不同的 class 当它有两个时,我知道事实上它会是 <p> 标签,但 <p> 标签的内容各不相同线。

Alvin Bunk - 使用你在 Edit two 中的代码已经很接近了,但无论如何它仍然会输出 classes 为 0 我不确定为什么因为我在你的 twigfiddle 文件中看到它起作用了,也许它是因为它是 Drupal 8。休闲是我如何将您的代码集成到模板中:

 <div{{ attributes.addClass(classes) }}>

    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>

    {% if multiple %} <div class="field__items"> {% endif %}

    {% set count = item|split('</p>') %}

    {% for item in items %}

      <div class="{{ count|length -1 }}">{{ item.content }}</div>

    {% endfor %} 

    {% if multiple %} </div> {% endif %}

  </div> 

我不知道我做错了什么,但结果总是 class="0" 我也尝试过 "item.content" 和 "item.content|raw" 但没有。

这是转储输出:

array(1) {
  [0]=>
  array(2) {
    ["content"]=>
    array(4) {
      ["#type"]=>
      string(14) "processed_text"
      ["#text"]=>
      string(52) "<p>CGS-2181-3105-9090</p>
<p>CGS-2181-3105-9090</p>"
      ["#format"]=>
      string(15) "restricted_html"
      ["#langcode"]=>
      string(3) "und"
    }
    ["attributes"]=>
    object(Drupal\Core\Template\Attribute)#2953 (1) {
      ["storage":protected]=>
      array(0) {
      }
    }
  }
}

更新 #3

根据上面的转储,我可以使用 {{ item.content["#text"] }} 获取字段的 html 值,输出 <p>CGS-2181-3105-9090</p> <p>CGS-2181-3105-9090</p> 但我不知道如何遍历它,我尝试设置一个变量 {% set count = '<p>' in item.content["#text"] %} 然后检查长度 {{ count|length }} 但无论如何我总是得到 1.

更新 #4:

使用 Alvin Bunk 的代码变体,我终于能够让它输出一个数字,这里是正确获取标签数量的标记:

 {% for item in items %}

          {% set count = item.content["#text"]|split('</p>') %}    

      <div class="{{ count|length -1 }}">{{ item.content }}</div>

    {% endfor %}

我将 set 变量移到 for 循环下方,并添加了转储中存在字符串的对象,现在它可以正常计数了。

您没有提供足够的信息,但我会推测一些事情:

项目是一个字符串,像这样:

<p>first line</p><p>Second line</p>

然后你可以使用下面的Twig代码:

{% set lines = item|split('</p>') %}

{% for element in lines if element != '' %}
    <div class="{{ loop.index }}">{{ element|raw }}</p></div>
{% endfor %}

在上面,我将 item 字符串拆分成一个名为 lines 的数组。然后我对 lines 元素执行 for 循环,并将 class 设置为循环索引(基于 1)。我输出为原始 html.

您会注意到,因为我在 '</p>' 上拆分,所以数组 lines 将包含最后一个元素,该元素为空;所以在我的 for 我必须添加 if element != ''.

Here is the twigfiddle 让您看到它正在运行。


编辑 #2 - 基于评论。

在那种情况下,这应该有效:

{% set item = '\n<p>first line</p>\n<p>Second line</p>\n' %}

{% set count = item|split('</p>') %}

<div class="{{ count|length -1 }}">{{ item|raw }}</div>

我更新了我的 twigfiddle,所以你可以看到变化。


编辑#3

您错过了一个更改,您需要拆分 items 而不是 item:

<div{{ attributes.addClass(classes) }}>

    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>

    {% if multiple %} <div class="field__items"> {% endif %}

    {% set count = items|split('</p>') %}

    {% for item in items %}
      <div class="{{ count|length -1 }}">{{ item.content }}</div>
    {% endfor %} 

    {% if multiple %} </div> {% endif %}

  </div>

编辑#4

您的计数集需要在循环之外。试试这个:

{% set count = item.content["#text"]|split('</p>') %}  
{% for item in items %}
      <div class="{{ count|length -1 }}">{{ item.content["#text"] }}</div>
{% endfor %}

另一种选择是制作一个用于计算段落的 Twig 扩展,但这对于这样的任务来说可能有点矫枉过正:

编辑 - 针对 Drupal 更新

namespace Drupal\twig_extension_parCount\TwigExtension;

use Drupal\Core\Template\TwigExtension;

class parCountExtension extends TwigExtension
{
    public function getFunctions() {
        return array(
            'parCount' => new \Twig_Function_Function(array('Drupal\twig_extension_parCount\TwigExtension\ParCountExtension', 'parCount')),
        );
    }

    public function getName() {
        return 'twig_extension_parCount.parCount_extension';
    }

    public static function parCount($str)
    {
        return substr_count($str, '<p>');
    }
}

然后在模板本身

{%  if (parCount(item) == 1) %}
   <div class="one">
{% elseif (parCount(item) == 2) %}
   <div class="two">
{% endif %}
{{ item }}</div>