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.

Comments

pdureau created an issue. See original summary.

just_like_good_vibes’s picture

Title: [2.0.0-beta2] Nested slots value when multiple sources » [2.0.0-beta3] Nested slots value when multiple sources
Issue summary: View changes

let's postpone this to beta3

pdureau’s picture

Issue summary: View changes
just_like_good_vibes’s picture

Title: [2.0.0-beta3] Nested slots value when multiple sources » [2.0.0-beta4] Nested slots value when multiple sources

let's postpone this for beta4

just_like_good_vibes’s picture

Assigned: just_like_good_vibes » pdureau
Status: Active » Needs review

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

pdureau’s picture

Title: [2.0.0-beta4] Nested slots value when multiple sources » Nested slots value when multiple sources
Assigned: pdureau » Unassigned
Status: Needs review » Postponed
lus’s picture

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)

pdureau’s picture

Status: Postponed » Postponed (maintainer needs more info)

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?

lus’s picture

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

field group config with patterns

(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 <li> inside which were all the 6 terms (wrapped with the HTML of the "Tag" pattern), instead of having 6x <li>.

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

pdureau’s picture

Status: Postponed (maintainer needs more info) » Active
pdureau’s picture

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

pdureau’s picture

Assigned: Unassigned » just_like_good_vibes
just_like_good_vibes’s picture

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

pdureau’s picture

Assigned: just_like_good_vibes » Unassigned
Status: Active » Postponed (maintainer needs more info)