Problem/Motivation

After creating a simple Tab and Tab section structure (complete with some sample content), upon saving the node, the following Twig error is displayed:

TypeError: Unsupported operand types: string + int in __TwigTemplate_50b45d73b2f3aed42e8c7384c3269f44->doDisplay() (line 215 of sites/default/files/php/twig/641b2ce01bdd8_paragraph--bp-tabs.html.t_JiV0wBml5bZeEjCJFMlyyWRdu/lqvEdco9u8Yxwi-Sgr_RutcqRYOef0bdL_fPCEa3b08.php).
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 367)
Twig\Template->display(Array) (Line: 379)
Twig\Template->render(Array, Array) (Line: 40)
Twig\TemplateWrapper->render(Array) (Line: 53)
twig_render_template('modules/contrib/bootstrap_paragraphs/templates/paragraph--bp-tabs.html.twig', Array) (Line: 372)
Drupal\Core\Theme\ThemeManager->render('paragraph', Array) (Line: 433)

Steps to reproduce

  • Fresh Drupal 10.0.5 site
  • PHP version 8.1
  • Dev version of Bootstrap Paragraphs
  • Latest release version of Bootstrap base theme
  • Content type with a single multi-valued Paragraphs field.
  • Node with 1 "Tabs" paragraph type and 2 nested "Tab section" paragraph types (each with Simple content).

This was happened upon during a Drupal class that I'm teaching, we also encountered several other similar issues, so expect some of our students to report those as well :)

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

ultimike created an issue. See original summary.

ultimike’s picture

Issue summary: View changes

Updated with more of the stack trace.

dalemoore’s picture

The problem seems to be from the introduction of this filter:

{% for key, item in content.bp_tab_section|filter(key => key|first != '#') %}

combined with

#{{ paragraph_id }}-{{ key + 1 }}

I don't think that filter does what it's supposed to do in Drupal 10. Before it was written like this:

{% for key, item in content.bp_tab_section if key|first != '#' %}

But that won't work in Drupal 10, either.

And you can't just break up the for and if statements like this:

{% for key, item in content.bp_tab_section  %}
{% if key|first != '#' %}

Because loop.first isn't working either. There are tons of other things in that array that start with #.

ultimike’s picture

We made some progress on a fix for this in class, but for some odd reason, we couldn't get the Twig |filter filter to work.

As a desperation play, I got things working with a for loop and an if-statement in the paragraph--bp-tabs.html.twig file.

      // Original code.
      {# for key, item in content.bp_tab_section|filter(key => key|first == '#') #}
      // Workaround code.
      {% for key, item in content.bp_tab_section %}
        {% if key|first != '#' %}
          <li role="presentation" class="{% if loop.first %}active{% endif %}"><a href="#{{ paragraph_id }}-{{ key + 1 }}" aria-controls="{{ item['#paragraph'].bp_tab_section_title.value }}" role="tab" data-toggle="tab">{{ item['#paragraph'].bp_tab_section_title.value }}</a></li>
        {% endif %}
      {% endfor %}

I would love for someone with stronger Twig skills than I to tell me where the issue lies with the |filter

thanks,
-mike

dalemoore’s picture

@ultimike does the loop.first not work for you too? I am using that same method, but the loop.first doesn't make the first tab active on page load. Wondering if it's something in my code or if not working for you as well?

ultimike’s picture

@dalemoore - I'm not 100% sure of what you're asking, but I can confirm that the "original code" (in my snippet above) does not work for me.

{% for key, item in content.bp_tab_section|filter(key => key|first == '#') %}

I spent some time trying to figure out why, to no avail. Which is why I ended up rewriting it (for my own sanity) using a for-loop and if-statement. But, I really don't understand what I'm missing in the "original code".

-mike

dalemoore’s picture

@ultimike I'm referring to this part:
<li role="presentation" class="{% if loop.first %}active{% endif %}"><a href="#{{ paragraph_id }}-{{ key + 1 }}" aria-controls="{{ item['#paragraph'].bp_tab_section_title.value }}" role="tab" data-toggle="tab">{{ item['#paragraph'].bp_tab_section_title.value }}</a></li>
If that part is working, when the page loads the first tab should be active and its tab panel should be shown. If it's not working, then no tab panel will be visible until you first click one of the tabs. For me, using the code you have works to make the tabs work, but the first tab and its panel aren't shown on page load because the "active" class isn't being applied.

amirez’s picture

@ultimike Apparently that Twig|filter {% for key, item in content.bp_tab_section|filter(key => key|first == '#') %} doesn't work on my site neither.
I tried your "workaround code", it did work but I got several warnings:
Warning: Array to string conversion in __TwigTemplate_50b45d73b2f3aed42e8c7384c3269f44->doDisplay() (line 141 of sites/default/files/php/twig/641b550d27442_paragraph--bp-tabs.html.t_JiV0wBml5bZeEjCJFMlyyWRdu/q6IuPi1QF5Vc0ZOn_ezvXfazGeN5Ju6PQDbYqX9W-jI.php).

afarsal’s picture

Hello,

I have same error. I change to

{#% for key, item in content.bp_tab_section|filter(key => key|first != '#') %#}
{% for key, item in content.bp_tab_section %}
{% if key|first != '#' %}

<li role="presentation" class="{% if loop.first %}active{% endif %}"><a href="#{{ paragraph_id }}-{{ key + 1 }}" aria-controls="{{ item['#paragraph'].bp_tab_section_title.value }}" role="tab" data-toggle="tab">{{ item['#paragraph'].bp_tab_section_title.value }}</a></li>
{% endif %}
{% endfor %}

...

{# Loops through the tab sections again to print the tab section bodies. #}
{#% for key, item in content.bp_tab_section|filter(key => key|first != '#') %#}
{% for key, item in content.bp_tab_section %}
{% if key|first != '#' %}

And for accordion same error for paragraph--bp-accordion.html.twig
and the same change

{# Loop through all of the accordion sections. #}
{#% for key, item in content.bp_accordion_section|filter(key => key|first != '#') %#}
{% for key, item in content.bp_accordion_section %}
{% if key|first != '#' %}

...

{% endif %}
{% endfor %}

After this change no error and tabs and accordions works fine for tabs without error. But for accordion, the accordions list is not displayed and activated immediately. You have to select the first tab to display the accordions.

Need a stable release and test also for bootstrap 5 (with barrio bootstrap 5 theme)

Thanks very well.
AFA

loopy1492’s picture

We are getting the same error on paragraph--bp-accordiaon.html.twig. It is not happy with the for+if.

This is similar to an issue where you can't do for ifs anymore similar to this:

 {% for key, item in content.field_card_links if key|first != '#' %}

has to be

{% for key, item in content.field_card_links %} 
          {% if key|first != '#' %}

So any single line for/ifs need to be changed to separate for and then ifs.

loopy1492’s picture

I suspect that the reason this wasn't flagged by the Upgrade Status module is because the |filter is broken not these templates themselves. My guess is that the definition uses if on a for tag which has been deprecated which seems strange to me, but researching the reasoning behind that is probably best left for another individual.

loopy1492’s picture

StatusFileSize
new13.75 KB
loopy1492’s picture

Title: Error when viewing Tab and Tab section paragraph types » Unsupported operand types: string + int in on multiple templates
loopy1492’s picture

Title: Unsupported operand types: string + int in on multiple templates » "Unsupported operand types: string + int" error on multiple templates
stacypendell’s picture

Patch fixes the problem for me. Same problem also seen on Drupal 9.5 when upgrading to the dev version of this module, and the patch fixed it there too.

keiserjb’s picture

The patch doesn't apply for me. Using the dev version of the module on 10.0.9.

keiserjb’s picture

Got it to work, another patch was messing it up.

yecmom’s picture

Hi,

Patch doesn't fix the problem for me on 9.5.9 : my carousel literally disappears though no error is logged.

Here's my code from line 169 of paragraph--bp-carousel.html.twig (slightly adjusted for Bootstrap 5):

…
{# Prints Carousel template. #}
{{ content|without('bp_slide_content','bp_slide_interval', 'bp_width', 'bp_background') }}
<div{{ attributes.addClass(classes).setAttribute('id', paragraph_id).setAttribute('data-bs-interval', slide_interval_classes).setAttribute('data-bs-ride', 'carousel') }}>
  <ol class="carousel-indicators">
    {% for key, item in content.bp_slide_content %}
      {% if key|first != '#' %}
        <li class="{% if loop.first %}active{% endif %}" data-bs-slide-to="{{ key }}" data-bs-target="#{{ paragraph_id }}"></li>
      {% endif %}
    {% endfor %}
  </ol>
  <div class="carousel-inner" role="list">
    {% for key, item in content.bp_slide_content %}
      {% if key|first != '#' %}
        <div class="paragraph--layout-slideshow__slide-{{ key + 1 }} item carousel-item{% if loop.first %}active{% endif %}" role="listitem">{{ item }}</div>
      {% endif %}
    {% endfor %}
  </div>
  <a class="left carousel-control" href="#{{ paragraph_id }}" role="button" data-bs-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </a>
  <a class="right carousel-control" href="#{{ paragraph_id }}" role="button" data-bs-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </a>
</div>

And here's my previous code, that works but isn't compatible with Drupal 10:

…
{# Prints Carousel template. #}
{{ content|without('bp_slide_content','bp_slide_interval', 'bp_width', 'bp_background') }}
<div{{ attributes.addClass(classes).setAttribute('id', paragraph_id).setAttribute('data-bs-interval', slide_interval_classes).setAttribute('data-bs-ride', 'carousel') }}>
  <ol class="carousel-indicators">
    {% for key, item in content.bp_slide_content if key|first != '#' %}
      <li class="{% if loop.first %}active{% endif %}" data-bs-slide-to="{{ key }}" data-bs-target="#{{ paragraph_id }}"></li>
    {% endfor %}
  </ol>
  <div class="carousel-inner" role="list">
    {% for key, item in content.bp_slide_content if key|first != '#' %}
      <div class="paragraph--layout-slideshow__slide-{{ key + 1 }} item carousel-item{% if loop.first %} active{% endif %}" role="listitem">{{ item }}</div>
    {% endfor %}
  </div>
  <a class="left carousel-control" href="#{{ paragraph_id }}" role="button" data-bs-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </a>
  <a class="right carousel-control" href="#{{ paragraph_id }}" role="button" data-bs-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </a>
</div>

If anyone could tell me what I did wrong, I would be very grateful !

Thanks!

platinum1’s picture

Same problem

steveoriol’s picture

Hello, @platinum1 and @yecmom,
I manage to make it works by adding manually the patch on issue :
https://www.drupal.org/project/bootstrap_paragraphs/issues/3221758
>> https://www.drupal.org/files/issues/2022-03-15/bootstrap_paragraphs-3221...

kerrymick’s picture

StatusFileSize
new5.88 KB

{% for key, item in content.bp_slide_content if key|first != '#' %}
needs to be updated to {% for key, item in content.bp_slide_content|filter((value, key) => key|first != '#') %}
For reference https://www.drupal.org/docs/upgrading-drupal/prepare-major-upgrade/prepa...
Patch attached.

shobhit_juyal’s picture

The same issue was coming in bp-accordion and patch suggested in #22 is fixing that issue as well.

draenen’s picture

#22 worked for us with 2.0.x-dev on Drupal 10.1.2

thejimbirch’s picture

Status: Active » Reviewed & tested by the community

Patch applies and has two approving comments.

thejimbirch’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.