From b050dbf465d30a90263587fe84c5ed1198af8ef0 Mon Sep 17 00:00:00 2001
From: nod_ <nod_@598310.no-reply.drupal.org>
Date: Thu, 29 Feb 2024 22:04:27 +0100
Subject: [PATCH] =?UTF-8?q?Issue=20#3062376=20by=20smustgrave,=20rlnorthcu?=
 =?UTF-8?q?tt,=20Krzysztof=20Doma=C5=84ski,=20ravi.shankar,=20robpowell,?=
 =?UTF-8?q?=20acbramley,=20Abhijith=20S,=20larowlan,=20Anybody,=20lauriii,?=
 =?UTF-8?q?=20phenaproxima,=20brandonratz,=20danflanagan8,=20quietone,=20l?=
 =?UTF-8?q?ongwave:=20Template=20suggestions=20for=20custom=20block=20view?=
 =?UTF-8?q?=20modes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../block_content/block_content.module        | 31 +++++++
 .../Kernel/BlockTemplateSuggestionsTest.php   | 86 +++++++++++++++++++
 2 files changed, 117 insertions(+)
 create mode 100644 core/modules/block_content/tests/src/Kernel/BlockTemplateSuggestionsTest.php

diff --git a/core/modules/block_content/block_content.module b/core/modules/block_content/block_content.module
index c63c0cfc9aeb..137455fc0cbf 100644
--- a/core/modules/block_content/block_content.module
+++ b/core/modules/block_content/block_content.module
@@ -5,6 +5,7 @@
  * Allows the creation of content blocks through the user interface.
  */
 
+use Drupal\block_content\BlockContentInterface;
 use Drupal\Core\Url;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\field\Entity\FieldConfig;
@@ -183,3 +184,33 @@ function _block_content_has_reusable_condition(array $condition, array $tables)
   }
   return FALSE;
 }
+
+/**
+ * Implements hook_theme_suggestions_HOOK_alter() for block templates.
+ */
+function block_content_theme_suggestions_block_alter(array &$suggestions, array $variables) {
+  $suggestions_new = [];
+  $content = $variables['elements']['content'];
+
+  $block_content = $variables['elements']['content']['#block_content'] ?? NULL;
+
+  if ($block_content instanceof BlockContentInterface) {
+    $bundle = $content['#block_content']->bundle();
+    $view_mode = strtr($variables['elements']['#configuration']['view_mode'], '.', '_');
+
+    $suggestions_new[] = 'block__block_content__view__' . $view_mode;
+    $suggestions_new[] = 'block__block_content__type__' . $bundle;
+    $suggestions_new[] = 'block__block_content__view_type__' . $bundle . '__' . $view_mode;
+
+    if (!empty($variables['elements']['#id'])) {
+      $suggestions_new[] = 'block__block_content__id__' . $variables['elements']['#id'];
+      $suggestions_new[] = 'block__block_content__id_view__' . $variables['elements']['#id'] . '__' . $view_mode;
+    }
+
+    // Remove duplicate block__block_content.
+    $suggestions = array_unique($suggestions);
+    array_splice($suggestions, 1, 0, $suggestions_new);
+  }
+
+  return $suggestions;
+}
diff --git a/core/modules/block_content/tests/src/Kernel/BlockTemplateSuggestionsTest.php b/core/modules/block_content/tests/src/Kernel/BlockTemplateSuggestionsTest.php
new file mode 100644
index 000000000000..92e529be166d
--- /dev/null
+++ b/core/modules/block_content/tests/src/Kernel/BlockTemplateSuggestionsTest.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Drupal\Tests\block_content\Kernel;
+
+use Drupal\block\Entity\Block;
+use Drupal\block_content\Entity\BlockContent;
+use Drupal\block_content\Entity\BlockContentType;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests the block_content_theme_suggestions_block() function.
+ *
+ * @group block_content
+ */
+class BlockTemplateSuggestionsTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'user',
+    'block',
+    'block_content',
+    'system',
+  ];
+
+  /**
+   * The BlockContent entity used for testing.
+   *
+   * @var \Drupal\block_content\Entity\BlockContent
+   */
+  protected $blockContent;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installEntitySchema('block_content');
+
+    // Create a block content type.
+    $block_content_type = BlockContentType::create([
+      'id' => 'test_block',
+      'label' => 'A test block type',
+      'description' => "Provides a test block type.",
+    ]);
+    $block_content_type->save();
+
+    $this->blockContent = BlockContent::create([
+      'info' => 'The Test Block',
+      'type' => 'test_block',
+    ]);
+    $this->blockContent->save();
+  }
+
+  /**
+   * Tests template suggestions from block_content_theme_suggestions_block().
+   */
+  public function testBlockThemeHookSuggestions() {
+    // Create a block using a block_content plugin.
+    $block = Block::create([
+      'plugin' => 'block_content:' . $this->blockContent->uuid(),
+      'region' => 'footer',
+      'id' => 'machine_name',
+    ]);
+
+    $variables['elements']['#id'] = $block->id();
+    $variables['elements']['#configuration']['provider'] = 'block_content';
+    $variables['elements']['#configuration']['view_mode'] = 'full';
+    $variables['elements']['content']['#block_content'] = $this->blockContent;
+    $suggestions_empty = [];
+    $suggestions_empty[] = 'block__block_content__' . $block->uuid();
+    $suggestions = block_content_theme_suggestions_block_alter($suggestions_empty, $variables);
+
+    $this->assertSame([
+      'block__block_content__' . $block->uuid(),
+      'block__block_content__view__full',
+      'block__block_content__type__test_block',
+      'block__block_content__view_type__test_block__full',
+      'block__block_content__id__machine_name',
+      'block__block_content__id_view__machine_name__full',
+    ], $suggestions);
+  }
+
+}
-- 
GitLab