Unverified Commit bbf39c43 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3020876 by alex_optim, sakiland, batkor, pfrenssen, mohit_aghera,...

Issue #3020876 by alex_optim, sakiland, batkor, pfrenssen, mohit_aghera, i-trokhanenko, drclaw, iamdroid, Grayle, tim.plunkett, gun_dose, acbramley, Chris Burge, Sam152, longwave: Contextual links of reusable content blocks are not displayed when rendering entities built via Layout Builder

(cherry picked from commit a835a60cf86329154dd75af84a5e0078f3c6abb2)
parent b0c9000b
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\layout_builder\Access\LayoutPreviewAccessAllowed;
use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
use Drupal\layout_builder\Plugin\Block\InlineBlock;
use Drupal\layout_builder\LayoutBuilderEvents;
use Drupal\views\Plugin\Block\ViewsBlock;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -124,9 +125,31 @@ public function onBuildRender(SectionComponentBuildRenderArrayEvent $event) {
        '#base_plugin_id' => $block->getBaseId(),
        '#derivative_plugin_id' => $block->getDerivativeId(),
        '#weight' => $event->getComponent()->getWeight(),
        'content' => $content,
      ];

      // Place the $content returned by the block plugin into a 'content' child
      // element, as a way to allow the plugin to have complete control of its
      // properties and rendering (for instance, its own #theme) without
      // conflicting with the properties used above, or alternate ones used by
      // alternate block rendering approaches in contributed modules. However,
      // the use of a child element is an implementation detail of this
      // particular block rendering approach. Semantically, the content returned
      // by the block plugin, and in particular, attributes and contextual links
      // are information that belong to the entire block. Therefore, we must
      // move these properties from $content and merge them into the top-level
      // element.
      if (isset($content['#attributes'])) {
        $build['#attributes'] = $content['#attributes'];
        unset($content['#attributes']);
      }
      // Hide contextual links for inline blocks until the UX issues surrounding
      // editing them directly are resolved.
      // @see https://www.drupal.org/project/drupal/issues/3075308
      if (!$block instanceof InlineBlock && !empty($content['#contextual_links'])) {
        $build['#contextual_links'] = $content['#contextual_links'];
      }
      $build['content'] = $content;

      if ($event->inPreview()) {
        if ($block instanceof PreviewFallbackInterface) {
          $preview_fallback_string = $block->getPreviewFallbackString();
+4 −0
Original line number Diff line number Diff line
layout_builder_test:
  title: 'Test contextual link'
  route_name: '<front>'
  group: 'layout_builder_test'
+43 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\layout_builder_test\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides a 'TestAttributes' block.
 *
 * @Block(
 *   id = "layout_builder_test_test_attributes",
 *   admin_label = @Translation("Test Attributes"),
 *   category = @Translation("Test")
 * )
 */
class TestAttributesBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [
      '#attributes' => [
        'class' => ['attribute-test-class'],
        'custom-attribute' => 'test',
      ],
      '#markup' => $this->t('Example block providing its own attributes.'),
      '#contextual_links' => [
        'layout_builder_test' => ['route_parameters' => []],
      ],
    ];
    return $build;
  }

}
+32 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ class LayoutBuilderTest extends BrowserTestBase {
    'layout_test',
    'block',
    'block_test',
    'contextual',
    'node',
    'layout_builder_test',
  ];
@@ -639,6 +640,37 @@ public function testPluginDependencies() {
    $assert_session->elementNotExists('css', '.block.menu--my-menu');
  }

  /**
   * Tests that block plugins can define custom attributes and contextual links.
   */
  public function testPluginsProvidingCustomAttributesAndContextualLinks() {
    $assert_session = $this->assertSession();
    $page = $this->getSession()->getPage();

    $this->drupalLogin($this->drupalCreateUser([
      'access contextual links',
      'configure any layout',
      'administer node display',
    ]));

    $this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default');
    $this->submitForm(['layout[enabled]' => TRUE], 'Save');
    $page->clickLink('Manage layout');
    $page->clickLink('Add section');
    $page->clickLink('Layout Builder Test Plugin');
    $page->pressButton('Add section');
    $page->clickLink('Add block');
    $page->clickLink('Test Attributes');
    $page->pressButton('Add block');
    $page->pressButton('Save layout');

    $this->drupalGet('node/1');

    $assert_session->elementExists('css', '.attribute-test-class');
    $assert_session->elementExists('css', '[custom-attribute=test]');
    $assert_session->elementExists('css', 'div[data-contextual-id*="layout_builder_test"]');
  }

  /**
   * Tests the interaction between full and default view modes.
   *