Allow to alter the build of a Pattern Layout

Created on 19 April 2024, 5 months ago
Updated 21 May 2024, 4 months ago

Problem/Motivation

There is no way to alter the build of a Pattern Layout. In some very specific cases, it can be handy to allow so.
For example programatically alter the variant of a pattern layout.

Steps to reproduce

  • Have a block content with a media image
  • The media image display is configured to use a pattern layout and has variants. Pattern could be: pattern_image
  • Add a list text field with, for now, hard coded the variants for the pattern layout. Variants could be: image_only, text_on_image, image_with_caption
  • When placing the block, allow to have the vied mode of the media item to be selected and the variant (as list field)
  • With the alter, you can now programatically get and set the variant

Proposed resolution

Provide the alter hook

Remaining tasks

Review MR

User interface changes

-

API changes

New alter hook for the Pattern Layout.

Data model changes

-

Feature request
Status

Closed: works as designed

Version

1.0

Component

UI Patterns Layouts

Created by

🇧🇪Belgium tim-diels Belgium 🇧🇪

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

Merge Requests

Comments & Activities

  • Issue created by @tim-diels
  • Status changed to Needs review 5 months ago
  • 🇧🇪Belgium tim-diels Belgium 🇧🇪

    Provided MR.

  • Pipeline finished with Success
    5 months ago
    Total: 288s
    #150877
  • Status changed to Postponed: needs info 5 months ago
  • 🇫🇷France pdureau Paris

    Hi Tim,

    Thanks for your proposal.

    So, the idea is to alter component configuration in the just before we build the renderable:

      public function build(array $regions) {
        $configuration = $this->getConfiguration();
        ...
        $this->moduleHandler->alter('ui_patterns_layouts_display', $configuration, $this, $regions);
    
        return [
          '#type' => 'pattern',
          '#id' => $this->getPluginDefinition()->get('additional')['pattern'],
          '#fields' => $fields,
          '#variant' => $configuration['pattern']['variant'],
        ] + $this->elementInfo->getInfo('pattern');
      }

    However, the configuration is only used for the variant after that. This is your need. But, it doesn't fit with the hook naming. We need a configuration alter hook doing more. Or we need a variant alterer doing the same. And I am afraid the later one is to specific.

    What do you think?

    Also, we need to be sure that this mechanism can be done also in UI Patterns 2.x and done in the same way with the 5 plugin types natively supported by UI Patterns 2 (layout, block field formatters, view style & view row) and can also be used/implemented in contrib space (DS field, field group formatter...)

  • 🇫🇷France pdureau Paris

    To not be limited to variant modification while altering $configuration, we can alter the renderable instead.

      public function build(array $regions) {
        ...
        $build = [ 
          '#type' => 'pattern',
          '#id' => $this->getPluginDefinition()->get('additional')['pattern'],
          '#fields' => $fields,
          '#variant' => $configuration['pattern']['variant'],
        ] + $this->elementInfo->getInfo('pattern');
        $build = $this->moduleHandler->alter('ui_patterns_layouts_display', $build);
        return $build;
      }

    So, why not using a preprocess hook (with the "layout" #context) instead?

    Because there are 2 issues:

    • currently, we have a preprocess hook for each pattern and no preprocess hook for all patterns
    • pattern preprocess hook are forbidden by SDC API, so will be removed in UI Patterns 2.x. And there are no #context equivalent in UI Patterns 2.x

    Another solution will be a hook_element_info_alter with a "#pre_render" (without using #context):

    • works for all patterns
    • will still work with UI Patterns 2 (after small changes)
    function hook_element_info_alter(array &$types) {
      if (isset($types['pattern'])) {
        array_unshift($types['pattern']['#pre_render'], 'my_callback');
      }
    }

    So, you may not need to add a specific hook to achieve your goal.

  • 🇧🇪Belgium tim-diels Belgium 🇧🇪

    Hey Pierre, much appreciated the time you put into this.
    After our call, I went a different route that you suggested me.

    For anyone else I've used a hook_preprocess_<PATTERN_ID> to alter the variant.
    You can always ping me if you need more info.

  • Status changed to Closed: works as designed 4 months ago
Production build 0.71.5 2024