[2.0.0-beta2] Nested slots value when multiple sources

Created on 1 August 2024, 10 months ago

In UI Patterns 1.x and UI Patterns 2.x, we can put many sources inside a single slot. Each source is a renderable and the slot is a list of those renderables.

If I put a single WysiwygWidget, I have a single renderable:

[
  "#type" => "processed_text"
  "#text" => "<p>Hello</p>"
  "#format" => "basic_html"
]

Because of this rule in ComponentElementBuilder::buildSlot():

    if (count($build["#slots"][$slot_id]) === 1) {
      $build["#slots"][$slot_id] = $build["#slots"][$slot_id][0];
    }

If I put 2 WysiwygWidget, I have a list of 2 renderables, of for each source:

 [
  [
    "#type" => "processed_text"
    "#text" => "<p>Hello</p>"
    "#format" => "basic_html"
  ],
  [
    "#type" => "processed_text"
    "#text" => "<p>World</p>"
    "#format" => "basic_html"
  ]
]

Problem/Motivation

However, sometimes, a source renderable is itself a list of renderables.

For example, in a view, with a WysiwygWidget and ViewRowsSource, I have nested lists of renderables:

[
  [
    "#type" => "processed_text"
    "#text" => "Hello"
    "#format" => "basic_html"
  ],
  [
    [
      #theme" => "node",
      "#node" => Drupal\node\Entity\Node {},
      "#view_mode" => "teaser"
    ],
    [
      #theme" => "node",
      "#node" => Drupal\node\Entity\Node {},
      "#view_mode" => "teaser"
    ]
  ]
]

It may not work well with component template looping on a slot and expecting a single level:

      {% for tab in items %}
        <li role="presentation">
          {{ tab }}
        </li>
      {% endfor %}

Proposed resolution

1. Pierre's: a configless automatic rule or nothing

For example, flatten the slot values, only first level, only when multiple sources, only when one a source renderable is a list of renderable (after normalization):

[
  [
    "#type" => "processed_text"
    "#text" => "Hello"
    "#format" => "basic_html"
  ],
  [
    #theme" => "node",
    "#node" => Drupal\node\Entity\Node {},
    "#view_mode" => "teaser"
  ],
  [
    #theme" => "node",
    "#node" => Drupal\node\Entity\Node {},
    "#view_mode" => "teaser"
  ]
]

Or an other rule... If no automatic rule is possible, do nothing.

1. Mikael's: add an option in ComponentSlotsForm

For example, a checkbox to decide if we flat the list or not.

📌 Task
Status

Active

Version

2.0

Component

Code

Created by

🇫🇷France pdureau Paris

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

Comments & Activities

  • Issue created by @pdureau
  • 🇫🇷France just_like_good_vibes PARIS

    let's postpone this to beta3

  • 🇫🇷France just_like_good_vibes PARIS

    let's keep the current implementation intact about "unfolding" render arrays.
    let's take this decision, Pierre?

  • Issue was unassigned.
  • Status changed to Postponed 4 months ago
  • Hi. Do you have some custom solution for that sort of cases ? Because we were struggling with this problem and we eventually came up with the idea to use an extra field (which I did not find great, it was for the pattern Tag Group - from UI Suite DSFR, we had multiple Taxonomy fields with multiple cardinality)

  • 🇫🇷France pdureau Paris

    Hi Lus,

    Thanks for using UI Patterns 2. Can you tell us how is it an issue for you? What is the technical problem you meet?

  • Sure. Will use a real life example coming from UI Suite DSFR.
    For the context, we have used UI Patterns: 1.10.0, UI Suite DSFR: 1.0.1,

    We've used a pattern "Tag Group" with this html structure:

    {% if tags %}
      {% set tags = tags is sequence ? tags : [tags] %}
      <ul{{ attributes.addClass('fr-tags-group') }}>
        {% for tag in tags %}
          <li>{{ tag }}</li>
        {% endfor %}
      </ul>
    {% endif %}
    

    In the BO, we've created a Field group which used this pattern, inside it, we've added two fields (sources) of type entity ref. Taxonomy term, with a multiple cardinality, each one uses a pattern "Tag":

    (hope u can see the details)
    Then, inside the content, for both field, we've added 3 values. But the end result was that we got a single "

  • " inside which were all the 6 terms (wrapped with the HTML of the "Tag" pattern), instead of having 6x "
  • ".

    Feel free to ask for further clarification if it's not clear.

  • Status changed to Active 12 days ago
  • 🇫🇷France pdureau Paris

    Hi @lus just a side note while waiting for the expected answer: {% set tags = tags and tags is not sequence ? [tags] : tags %} is better/safer than {% set tags = tags is sequence ? tags : [tags] %}

  • 🇫🇷France just_like_good_vibes PARIS

    hello,
    after a small discussion, it appears the needs should be addressed with a custom source, that would make the data extraction as needed and return the appropriate data

  • Production build 0.71.5 2024