【问题标题】:Twig: how to check the inner html content of a fieldTwig:如何检查字段的内部 html 内容
【发布时间】:2017-06-27 21:05:43
【问题描述】:

我有一个字段,该字段可以有一两行 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 有一个类,如果项目中有两行,我希望父 div 有一个不同的类

更新 #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 有一个类,当它有一个 &lt;p&gt; 标签和一个不同的类,当它有两个标签时,我知道事实上它将是 &lt;p&gt; 标签,但 &lt;p&gt; 标签的内容各不相同仅以第一行和第二行为例,但内容是用户在填写字段后生成的,无论是使用一行还是两行。

Alvin Bunk - 使用 Edit 2 中的代码已接近,但无论如何它仍会将类输出为 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 值,它输出 &lt;p&gt;CGS-2181-3105-9090&lt;/p&gt; &lt;p&gt;CGS-2181-3105-9090&lt;/p&gt; 但我不知道如何遍历它,我尝试设置一个变量 {% set count = '&lt;p&gt;' 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 %}

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

【问题讨论】:

  • 你能否展示一下你是如何将items 作为参数传递给你的控制器的?
  • 我到底是怎么显示的?
  • 我不确定 Drupal 是如何完成的,我只熟悉 Symfony。在 Symfony 中,它会这样完成:return $this-&gt;render('mytwigfile.html.twig', array( 'items' =&gt; $item-&gt;getContent() )); 这就是我希望你做的,在你的 items 对象上调用“getContent()”函数,所以 Twig 文件只获取一个字符串而不是一个对象(或数组)。
  • 我目前也不知道如何在drupal中做到这一点,我已经查看了api但这是很多php文件和函数,到目前为止我还没有找到任何具体的东西,似乎是通过字段模块传递,但我无法从所有代码中做出正面或反面,如果我发现任何东西,我会继续寻找并更新你。谢谢
  • 我添加了 EDIT #4。试试吧。我的想法不多了。 Drupal 文档不是很有帮助。

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


【解决方案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。

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

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


编辑 #2 - 基于 cmets。

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

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

【讨论】:

  • 我认为 OP 不想分割多行“项目”的行并以不同的方式相互设置样式。我从他的描述中了解到,如果“项目”中有一行,他想要一种样式,如果“项目”中有两行,他想要另一种样式。你怎么看?
  • 您的回答绝对有帮助。我们必须看看 OP 到底想要什么。从他的帖子中肯定不清楚。
  • Honza 说的是真的,如果项目中只有一行,我希望父 div 有一个类,如果项目中有两行,我希望父 div 有一个不同的类
  • 查看我的 EDIT #2 更改。那应该解决它。顺便说一句,班级的数字好吗?我没有想过拼出数字,但也可能有一种简单的方法可以做到这一点。如果是这样,请告诉我您将使用的最大数量。
  • 您的编辑 #2 已接近但仍无法正常工作,请参阅更新 #2。
【解决方案2】:

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

【讨论】:

  • 这段代码看起来也很有希望,但我不知道如何将命名空间功能集成到 drupal 中的 twig 中。我认为要使用这个,我必须通过 php 作为 .theme 文件上的字段预处理来执行函数,然后从 twig 调用该函数,但我不知道从哪里开始。
  • Drupal 的扩展代码已更新。如果您对 Twig 扩展感兴趣,可以在此处找到更复杂的示例,包括描述:api.drupal.org/api/drupal/…
  • 你是正确的,你在那里的函数代码使用了drupal api,但是这个代码必须从某种模块中调用才能使用它不能插入到树枝模板中,这可能是一种更好的方式,或者至少是更多的drupal方式,但我对我的编码没有足够的信心来创建一个模块及其所有部分。尽管如此还是非常感谢,我仍然会保留代码,看看我将来如何使用它。
猜你喜欢
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 2017-10-22
  • 1970-01-01
  • 2019-01-19
  • 1970-01-01
  • 2013-04-01
  • 2017-08-03
相关资源
最近更新 更多