[2.0.x] Ensure using always the "replaced " component structure

Created on 7 May 2025, about 1 month ago

Problem/Motivation

The "replace" replaces a existing component inside the find method. Layout builder and library using the plugin definition instead the replaced plugin. This leads to wrong slots/props in layout builder and library.

✨ Feature request
Status

Active

Version

2.0

Component

Code

Created by

🇩🇪Germany Christian.wiedemann

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

Merge Requests

Comments & Activities

  • Issue created by @Christian.wiedemann
  • 🇩🇪Germany Christian.wiedemann

    Can you check this if the behavior is right now. Now the component with "replaces" inside is taken into account for building slots and props in layout builder and library. But still both component appears. Is this right?

  • 🇫🇷France pdureau Paris

    I think we need to leverage this Core issue ✨ SDC: Add a method to retrieve only components not replaced by others Needs work to:

    • show all components in the component library (ui_patterns_library)
    • but only the non-replaced components:
      • in the components selector (ui_patterns) when #render_slots is true
      • in specific integration when #render_slots is false (so in ui_patterns_layouts)

    If we don't want to wait for the Core issue to be fixed, let's accelerate it and make a compatible change while waiting.

    Don't you think?

  • 🇩🇪Germany Christian.wiedemann

    Yes you are right but I think we should also hide the component in the library.

  • 🇩🇪Germany Christian.wiedemann

    So I hide the components with a "replaces" from component selector / Layout and UIP UI. Inside the library it is a bit more complicated. Right now both components are visible but htis does not make sense from my point of view.

    We should also hide the "replaces" component and inside the single view of the component we should switch from "replaces" to "Replaced by". Good?

  • 🇫🇷France pdureau Paris

    Yes you are right but I think we should also hide the component in the library.

    I don't have strong opinion about this. So, let's do as you want or let's ask the team.

    We should also hide the "replaces" component and inside the single view of the component we should switch from "replaces" to "Replaced by". Good?

    We must hide the replaced component and show only the replacing component, right? So what would be the use of showing "Replaced by" info in replaced components?

  • 🇫🇷France pdureau Paris
  • 🇩🇪Germany Christian.wiedemann

    For clearification:
    A Card from a base theme (BaseCard) is overwriten with a SubCard inside a theme.
    So right now I hide SubCard everywhere because this SubCard should not be used for mapping or something else. It should always used the BaseCard as mapping target but with props/slots and template from the SubCard. We must ensure that already existing configs are working so we can't hide the BaseCard. Inside the library I would also recommend to hide the SubCard and only render the BaseCard with new slots and props and twig template and only say with "Replaced By" that the subcard is used here.
    Hope it is more clear now.

  • 🇫🇷France pdureau Paris

    So, your proposal is:

    • On the Component selector and the Library, show only the replaced component ("BaseCard") with its ID
    • But, once selected, show the form of the replacement ("SubCard")

    What happen if a component is replaced by many others ("SubCard1" and "SubCard2") ? What happen if a replacement is replaced ("SubSubCard") ? I guess we need to follow the SDC rendering logic.

  • 🇫🇷France pdureau Paris

    Also, what about stories? We merge?

  • 🇫🇷France pdureau Paris
  • 🇩🇪Germany Christian.wiedemann

    I finalized the library integration and fixed some implementation detaisl. Ready to merge from my side.

    I also checked the negiation mechanisms for the component itself. It is quite straightforward. It is done in ComponentNegotiator with. First it is checked if the component is in your theme and than the module weight is used for filtering the right component id.

    $matches = array_filter(
          $all_definitions,
          static fn(array $definition) => $component_id === ($definition['replaces'] ?? NULL),
        );
        $negotiated_plugin_id = $this->maybeNegotiateByTheme($matches);
        if ($negotiated_plugin_id) {
          return $negotiated_plugin_id;
        }
        return $this->maybeNegotiateByModule($matches);
    

    So there is only one replacement which is taken. The patch uses also the ComponentNegotiator to return the right id for the definition itself.

  • 🇫🇷France pdureau Paris

    To review.

Production build 0.71.5 2024