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

时间:2017-02-09 17:59:56

标签: symfony drupal twig drupal-theming drupal-8

我有一个字段,该字段可以有一行或两行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有一个类,如果项目中只有一行,如果项目中有两行,则需要另一个类

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

{%
  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在有一个<p>标记时有一个类,而在有两个时有一个不同的类,我知道它实际上是<p>个标签,但是<p>的内容1}}标签变化我只是使用第一行和第二行作为示例,但是内容是用户在填充字段后生成的,无论是使用一行还是两行。

Alvin Bunk - 使用来自Edit 2的代码得到了关闭但它仍然会将类输出为0而不管我不知道为什么因为我在你的twigfiddle文件中看到它有效,也许是因为它&#39 ; 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> 

我不知道我做错了什么,但总是出现在班级=&#34; 0&#34; 我也试过&#34; item.content&#34;和&#34; item.content | raw&#34;但没什么。

这是转储输出:

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"] }}的{​​{1}}来获取字段的html值,但我不知道如何遍历它,我试图设置变量{{1}然后检查长度,如<p>CGS-2181-3105-9090</p> <p>CGS-2181-3105-9090</p>,但我总是得到1。

更新#4:

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

{% set count = '<p>' in item.content["#text"] %}

我将set变量移动到for循环下面并添加了转储中存在字符串的对象,现在它正确计算。

2 个答案:

答案 0 :(得分:1)

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

Item是一个字符串,如下所示:

<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循环,并将类设置为循环索引(基于一个)。我输出为原始html。

你会注意到,因为我在'</p>'上分裂,所以数组lines将包含一个最后一个为null的元素;所以在我看来,我必须添加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 %}

答案 1 :(得分:1)

另一个选择是制作一个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>