Problem/Motivation

My scenario involves the placement of a views block in layout builder for a content type. During the rendering process, section and section component information is not available once the views block build method is called. I need the ability to inject the section layout ID and the component region values into the views result row/item before it reaches an implementation of hook_preprocess_node().

Proposed resolution

After much digging, I found the SECTION_COMPONENT_BUILD_RENDER_ARRAY event. Using that event and a new one for SECTION_BUILD_RENDER_ARRAY, an event listener can be used to store the information needed in drupal_static() that can be accessed in the implementation of hook_preprocess_node().

Remaining tasks

Add tests.

User interface changes

API changes

Data model changes

Release notes snippet

Comments

weekbeforenext created an issue. See original summary.

weekbeforenext’s picture

Issue summary: View changes
StatusFileSize
new5.6 KB

This is a patch that applies cleanly to 8.7.x.

weekbeforenext’s picture

tim.plunkett’s picture

Version: 8.7.7 » 8.9.x-dev
Issue summary: View changes
Status: Active » Needs work
Issue tags: +Blocks-Layouts, +Needs tests

While the implementation you describe above sounds particularly terrifying, it seems absolutely correct to have Section mirror SectionComponent in their toRenderArray() approaches.

+++ b/core/modules/layout_builder/src/Section.php
@@ -81,14 +82,17 @@ public function __construct($layout_id, array $layout_settings = [], array $comp
+    $this->eventDispatcher()->dispatch(LayoutBuilderEvents::SECTION_BUILD_RENDER_ARRAY, $event);
     $regions = [];
     foreach ($this->getComponents() as $component) {
       if ($output = $component->toRenderArray($contexts, $in_preview)) {
         $regions[$component->getRegion()][$component->getUuid()] = $output;
       }
     }

Similar to how \Drupal\layout_builder\SectionComponent::toRenderArray() consists solely of the dispatched event, this current implementation should be moved to an event subscriber with a priority of 100. That will allow custom event subscribers to occur before or after this default code, with the non-explicit priority code running *after* (as a sort of alter).

Note also that \Drupal\Tests\layout_builder\Unit\SectionRenderTest should be updated/adapted to reflect the changes in rendering flow. See \Drupal\Tests\layout_builder\Unit\SectionComponentTest for inspiration.

Bumping to 8.9.x, but this might be a 9.1.x issue, I'm not sure of the timing/rules with that currently.

weekbeforenext’s picture

Issue summary: View changes

Thanks for taking a look so quickly.

I updated the Proposed solution to replace "tempstore" with "drupal_static()" which hopefully seems a little less terrifying. :) It's working which is hopeful.

I think I understand your suggested changes. I gave it a shot yesterday but broke things and backed out of it. I'll keep this on my radar and try again.

I joined the #layouts channel on Drupal Slack, so feel free to ping me if you want to chat about potentially better solutions for this sort of issue.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new10.31 KB
new5.81 KB

Here's a patch that implements #4.
It still needs explicit test coverage to prove another subscriber can affect the output. The previous patch did not call $event->getBuild()

Note: The order of arguments to dispatch() changed in D9, so this will not work as-is for D8.

Status: Needs review » Needs work

The last submitted patch, 7: 3101655-section_event-7.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new11.11 KB
new821 bytes

That's what happens when you only run the unit tests before posting...

Status: Needs review » Needs work

The last submitted patch, 9: 3101655-section_event-9.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new11.16 KB
new1.28 KB

I knew I was missing something, passing $regions to setBuild() did not feel right.

neograph734’s picture

Status: Needs review » Needs work

@tim.plunkett, how did you manage to get this test to pass? I am getting the following error on my site:

TypeError: Argument 2 passed to Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher::dispatch() must be an instance of Symfony\Component\EventDispatcher\Event or null, string given, called in /var/www/html/web/core/modules/layout_builder/src/Section.php on line 86 in Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (line 89 of core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php).

Which makes sense because your patch swapped the event name and the event.

+ $this->eventDispatcher()->dispatch($event, LayoutBuilderEvents::SECTION_BUILD_RENDER_ARRAY);

In SectionComponent.php we see this inversed:

$this->eventDispatcher()->dispatch(LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY, $event);

Manually swapping them back makes the error go away.

This works great in conjunction with #3044117: Add getter for layout object in Layout Builder's ConfigureSectionForm. Allowing one to easily set third party settings by altering the configuration form and then having access to them in this event. Many thanks for the effort.

tim.plunkett’s picture

Status: Needs work » Needs review

This patch is written for 9.1, the development version of Drupal. As a feature request, it will not be backported to D8.

neograph734’s picture

Ah apologies, I was under the assumption that I had spun up a 9.1 site, but it appeared to be 9.0.6 instead. I'll give it another shot later this week.

neograph734’s picture

I did spin up a 9.1 instance, but patched another site in the wrong folder... It works and for me it is RTBC :)

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

claudiu.cristea’s picture

Status: Needs review » Closed (duplicate)
Parent issue: » #3062862: Third party should be allowed to alter the section render array

#3062862: Third party should be allowed to alter the section render array is doing the same but it's older. Closing this as duplicate.