From 76fac09c84221745e1caa1bae9745c6b27089972 Mon Sep 17 00:00:00 2001
From: Lauri Eskola <lauri.eskola@acquia.com>
Date: Tue, 31 Oct 2023 14:35:14 +0200
Subject: [PATCH] Issue #3391702 by pdureau, smustgrave, e0ipso: SDC
 ComponentElement: Transform slots scalar values to #plain_text instead of
 throwing an exception

---
 .../sdc/src/Element/ComponentElement.php      |  7 +++-
 .../tests/src/Kernel/ComponentRenderTest.php  | 36 +++++++++++++++++--
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/core/modules/sdc/src/Element/ComponentElement.php b/core/modules/sdc/src/Element/ComponentElement.php
index de540ae24d63..b7e259d762ae 100644
--- a/core/modules/sdc/src/Element/ComponentElement.php
+++ b/core/modules/sdc/src/Element/ComponentElement.php
@@ -105,9 +105,14 @@ private function generateComponentTemplate(
     $template .= sprintf('{%% embed \'%s\' %%}', $id);
     $template .= PHP_EOL;
     foreach ($slots as $slot_name => $slot_value) {
+      if (\is_scalar($slot_value)) {
+        $slot_value = [
+          "#plain_text" => (string) $slot_value,
+        ];
+      }
       if (!Utilities::isRenderArray($slot_value)) {
         $message = sprintf(
-          'Unable to render component "%s". A render array is expected for the slot "%s" when using the render element with the "#slots" property',
+          'Unable to render component "%s". A render array or a scalar is expected for the slot "%s" when using the render element with the "#slots" property',
           $id,
           $slot_name
         );
diff --git a/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php b/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
index 331e71ef8f2c..ba8003bc345c 100644
--- a/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
+++ b/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
@@ -42,6 +42,7 @@ public function testRender(): void {
     $this->checkLibraryOverrides();
     $this->checkAttributeMerging();
     $this->checkRenderElementAlters();
+    $this->checkSlots();
     $this->checkInvalidSlot();
   }
 
@@ -284,7 +285,36 @@ public function checkRenderElementAlters(): void {
   }
 
   /**
-   * Ensure that the slots receive a render array when using the render element.
+   * Ensure that the slots allow a render array or a scalar when using the render element.
+   */
+  public function checkSlots(): void {
+    $slots = [
+      'This is the contents of the banner body.',
+      [
+        '#plain_text' => 'This is the contents of the banner body.',
+      ],
+    ];
+    foreach ($slots as $slot) {
+      $build = [
+        '#type' => 'component',
+        '#component' => 'sdc_test:my-banner',
+        '#props' => [
+          'heading' => $this->t('I am a banner'),
+          'ctaText' => $this->t('Click me'),
+          'ctaHref' => 'https://www.example.org',
+          'ctaTarget' => '',
+        ],
+        '#slots' => [
+          'banner_body' => $slot,
+        ],
+      ];
+      $crawler = $this->renderComponentRenderArray($build);
+      $this->assertNotEmpty($crawler->filter('#sdc-wrapper [data-component-id="sdc_test:my-banner"] .component--my-banner--body:contains("This is the contents of the banner body.")'));
+    }
+  }
+
+  /**
+   * Ensure that the slots throw an error for invalid slots.
    */
   public function checkInvalidSlot(): void {
     $build = [
@@ -297,11 +327,11 @@ public function checkInvalidSlot(): void {
         'ctaTarget' => '',
       ],
       '#slots' => [
-        'banner_body' => 'I am an invalid render array.',
+        'banner_body' => new \stdClass(),
       ],
     ];
     $this->expectException(InvalidComponentDataException::class);
-    $this->expectExceptionMessage('Unable to render component "sdc_test:my-banner". A render array is expected for the slot "banner_body" when using the render element with the "#slots" property');
+    $this->expectExceptionMessage('Unable to render component "sdc_test:my-banner". A render array or a scalar is expected for the slot "banner_body" when using the render element with the "#slots" property');
     $this->renderComponentRenderArray($build);
   }
 
-- 
GitLab