Bootstrap accordion paragraph twig template duplicates content if layout_paragraphs Section is used in Accordion Section

Created on 2 August 2023, 11 months ago
Updated 1 April 2024, 3 months ago

Problem/Motivation

I am using bootstrap_paragraphs along with layout_paragraphs β†’ for a better authoring experience. There have been a few bugs here and there but I have managed to make things work for the most part.

I ran into two issues with the accordion however, the second of which - while I have a workaround for - annoys me a bit.

Steps to reproduce

Create an Accordion paragraph and add an Accordion Section.
In the Accordion Section add a Layout Section paragraph and populate that with a few more paragraphs, e.g. Simple & Image.

First of all you will notice that nothing renders.

This is because of this line in templates/paragraph--bp-accordion.html.twig

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

If the outermost paragraph is a Section, then the first level of items in the array all start with #
The structure that the template expects is found inside the #root_components element of the array in this case.
To replicate the same logic I had to override the template in my custom module and change this logic:

{# Make sure we are iterating the proper array in case of multiple layouts #}
{# This fixes the bug where Accordion Paragraph Builder fields would not render #}
{% set found_non_hash_keys = false %}
{% for key, item in content.bp_accordion_section %}
  {% if key|first != '#' %}
    {% set found_non_hash_keys = true %}
  {% endif %}
{% endfor %}
{% if found_non_hash_keys %}    
  {% set iteratable = content.bp_accordion_section %}
{% else %}
  {% set iteratable = content.bp_accordion_section['#root_components'] %}
{% endif %}

{# Loop through all of the accordion sections. #}
{% for key, item in iteratable if key|first != '#' %}

I am ok with this solution and I am happy to submit it as a patch.

The second issue occurs further down the template and that I don't have a clear solution for:

{# Loop through all of the accordion section bodies. #}
{% for body_key, body_item in item['#paragraph'].bp_accordion_section_body %}

The issue here is that looping through all the items, in the case where the outermost paragraph is a Section results in item duplication due to the Section paragraph and it's children being all in the same level in the array. So for example assuming I had a section with two paragraphs in it:

[0] => Section
[1] => Simple
[2] => Image

What will render is the Section with the SImple and the Image, then the Simple, then the Image.

What I have done was to require the outermost paragraph for Accordion Sections to be Section and changed the loop thusly:

{% for body_key, body_item in item['#paragraph'].bp_accordion_section_body if (item['#paragraph'].bp_accordion_section_body[body_key].entity.bundle() == 'section') %}

This avoids the duplication as it prints only sections but it kinda forces me into a very specific configuration which I don't like.

Proposed resolution

I am not sure how to deal with this. Ideally this should be dealt outside of the template so that the proper array structure is there to be rendered.

Maybe on some preprocess function we need to load a paragraph if it's a section, look at it's children, and if those children are present in the array as standalone items remove them (?)

πŸ› Bug report
Status

Postponed: needs info

Component

Code

Created by

πŸ‡¬πŸ‡·Greece magtak

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

Comments & Activities

Production build 0.69.0 2024