diff --git a/core/lib/Drupal/Core/Plugin/ContextAwarePluginAssignmentTrait.php b/core/lib/Drupal/Core/Plugin/ContextAwarePluginAssignmentTrait.php index f9e349ed69e0a035b55616b4dd2ec9b8645da090..012bd30e7303d893528fe60c8cd1f1590b3bff33 100644 --- a/core/lib/Drupal/Core/Plugin/ContextAwarePluginAssignmentTrait.php +++ b/core/lib/Drupal/Core/Plugin/ContextAwarePluginAssignmentTrait.php @@ -53,7 +53,7 @@ protected function addContextAssignmentElement(ContextAwarePluginInterface $plug ]; } - if (count($options) > 1) { + if (count($options) > 1 || !$definition->isRequired()) { $assignments = $plugin->getContextMapping(); $element[$context_slot] = [ '#title' => $definition->getLabel() ?: $this->t('Select a @context value:', ['@context' => $context_slot]), @@ -63,6 +63,9 @@ protected function addContextAssignmentElement(ContextAwarePluginInterface $plug '#default_value' => !empty($assignments[$context_slot]) ? $assignments[$context_slot] : '', '#description' => $definition->getDescription(), ]; + if (!$definition->isRequired()) { + $element[$context_slot]['#empty_value'] = ''; + } } } return $element; diff --git a/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php b/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php index 21ee311c0e298c80399d0cc80cf2dc72eebbe431..219dd37e23e5ec081868439a38849d11306b3418 100644 --- a/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php +++ b/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php @@ -93,7 +93,7 @@ public function getContextMapping() { public function setContextMapping(array $context_mapping) { if ($this instanceof ConfigurablePluginInterface) { $configuration = $this->getConfiguration(); - $configuration['context_mapping'] = $context_mapping; + $configuration['context_mapping'] = array_filter($context_mapping); $this->setConfiguration($configuration); } else { diff --git a/core/modules/block/src/Tests/BlockUiTest.php b/core/modules/block/src/Tests/BlockUiTest.php index 532094265726dddffc5edc2e2046509fc79f14ee..25b7942a59e12c33a7ef0f39877f16b6f567ab99 100644 --- a/core/modules/block/src/Tests/BlockUiTest.php +++ b/core/modules/block/src/Tests/BlockUiTest.php @@ -207,7 +207,6 @@ public function testContextAwareBlocks() { $this->assertTrue(!empty($elements), 'The context-aware test block appears.'); $definition = \Drupal::service('plugin.manager.block')->getDefinition('test_context_aware'); $this->assertTrue(!empty($definition), 'The context-aware test block exists.'); - $edit = [ 'region' => 'content', 'settings[context_mapping][user]' => '@block_test.multiple_static_context:user2', @@ -217,6 +216,15 @@ public function testContextAwareBlocks() { $this->drupalGet(''); $this->assertText('Test context-aware block'); $this->assertRaw($expected_text); + + // Test context mapping allows empty selection for optional contexts. + $this->drupalGet('admin/structure/block/manage/testcontextawareblock'); + $edit = [ + 'settings[context_mapping][user]' => '', + ]; + $this->drupalPostForm(NULL, $edit, 'Save block'); + $this->drupalGet(''); + $this->assertText('No context mapping selected.'); } /** diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php index c4223d0ea79f94b7e52cf37c28596ea4cfcb66fd..013dbae75b8a7e3f1861ed084b8353c5c8d5414e 100644 --- a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php +++ b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php @@ -16,7 +16,7 @@ * id = "test_context_aware", * admin_label = @Translation("Test context-aware block"), * context = { - * "user" = @ContextDefinition("entity:user") + * "user" = @ContextDefinition("entity:user", required = FALSE) * } * ) */ @@ -31,7 +31,7 @@ public function build() { return array( '#prefix' => '
', '#suffix' => '
', - '#markup' => $user->getUsername(), + '#markup' => $user ? $user->getUsername() : 'No context mapping selected.' , ); }