"Unsupported operand types: string + int" error on multiple templates

Created on 22 March 2023, over 1 year ago
Updated 5 September 2023, 10 months ago

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 :)

🐛 Bug report
Status

Fixed

Version

2.0

Component

Code

Created by

🇺🇸United States ultimike Florida, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @ultimike
  • 🇺🇸United States ultimike Florida, USA

    Updated with more of the stack trace.

  • 🇺🇸United States dalemoore

    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 #.

  • 🇺🇸United States ultimike Florida, USA

    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

  • 🇺🇸United States dalemoore

    @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?

  • 🇺🇸United States ultimike Florida, USA

    @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

  • 🇺🇸United States dalemoore

    @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.

  • 🇺🇸United States Amirez Houston, TX

    @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).

  • 🇫🇷France afarsal

    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 != '#' %}

  • {{ item['#paragraph'].bp_tab_section_title.value }}
  • {% 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

  • 🇺🇸United States loopy1492

    We are getting the same error on paragraph--bp-accordiaon.html.twig. It is not happy with the filter and the {{ key+1 }}

  • @loopy1492 opened merge request.
  • 🇺🇸United States loopy1492

    I suspect that the reason this wasn't flagged by the Upgrade Status module is because the |filter is broken, not these templates themselves which seems strange to me, but researching that is probably best left for another individual.

  • 🇺🇸United States stacypendell

    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.

  • 🇺🇸United States keiserjb

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

  • 🇺🇸United States keiserjb

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

  • 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!

  • 🇺🇸United States platinum1

    Same problem

  • 🇫🇷France steveoriol Grenoble 🇫🇷

    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 Bootstrap 5 support Needs work
    >> https://www.drupal.org/files/issues/2022-03-15/bootstrap_paragraphs-3221...

  • 🇺🇸United States kerrymick Chicago

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

  • 🇮🇳India shobhit_juyal New Delhi

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

  • 🇺🇸United States draenen

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

  • Status changed to RTBC 10 months ago
  • 🇺🇸United States thejimbirch Cape Cod, Massachusetts

    Patch applies and has two approving comments.

  • Status changed to Fixed 10 months ago
  • 🇺🇸United States thejimbirch Cape Cod, Massachusetts
  • Automatically closed - issue fixed for 2 weeks with no activity.

  • Production build 0.69.0 2024