Skip to content
Snippets Groups Projects
Commit 66b87ec0 authored by Pierre Dureau's avatar Pierre Dureau
Browse files

Issue #3477573 by pdureau: Better stories slots processing

parent b96ad11e
No related branches found
No related tags found
No related merge requests found
......@@ -7,8 +7,8 @@ namespace Drupal\ui_patterns_legacy\Element;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Theme\ComponentPluginManager;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\ui_patterns\Element\ComponentElementAlter as UiPatternsComponentElementAlter;
use Drupal\ui_patterns_legacy\RenderableConverter;
use Drupal\ui_patterns_library\StoriesSyntaxConverter;
/**
* Renders a component story.
......@@ -22,13 +22,13 @@ class ComponentElementAlter implements TrustedCallbackInterface {
* The theme manager.
* @param \Drupal\Core\Theme\ComponentPluginManager $componentPluginManager
* The component plugin manager.
* @param \Drupal\ui_patterns\Element\ComponentElementAlter $componentElementAlter
* The component element alter.
* @param \Drupal\ui_patterns_library\StoriesSyntaxConverter $storiesConverter
* The stories syntax converter.
*/
public function __construct(
protected ThemeManagerInterface $themeManager,
protected ComponentPluginManager $componentPluginManager,
protected UiPatternsComponentElementAlter $componentElementAlter,
protected StoriesSyntaxConverter $storiesConverter,
) {
}
......@@ -70,7 +70,7 @@ class ComponentElementAlter implements TrustedCallbackInterface {
return $element;
}
$element["#story"] = $this->getStoryId($component["stories"]);
$element["#slots"] = $this->componentElementAlter->processStoriesSlots($element["#slots"] ?? []);
$element["#slots"] = $this->storiesConverter->convertSlots($element["#slots"] ?? []);
return $element;
}
......
......@@ -5,3 +5,4 @@ core_version_requirement: ^10.3 || ^11
package: "User interface"
dependencies:
- ui_patterns:ui_patterns
- ui_patterns:ui_patterns_library
......@@ -22,4 +22,4 @@ services:
arguments:
- "@theme.manager"
- "@plugin.manager.sdc"
- "@ui_patterns.component_element_alter"
- "@ui_patterns_library.stories_syntax_converter"
......@@ -6,7 +6,7 @@ namespace Drupal\ui_patterns_library\Element;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Theme\ComponentPluginManager;
use Drupal\ui_patterns\Element\ComponentElementAlter as UiPatternsComponentElementAlter;
use Drupal\ui_patterns_library\StoriesSyntaxConverter;
/**
* Renders a component story.
......@@ -18,12 +18,12 @@ class ComponentElementAlter implements TrustedCallbackInterface {
*
* @param \Drupal\Core\Theme\ComponentPluginManager $componentPluginManager
* The component plugin manager.
* @param \Drupal\ui_patterns\Element\ComponentElementAlter $componentElementAlter
* The component element alter.
* @param \Drupal\ui_patterns_library\StoriesSyntaxConverter $storiesConverter
* The stories syntax converter.
*/
public function __construct(
protected ComponentPluginManager $componentPluginManager,
protected UiPatternsComponentElementAlter $componentElementAlter,
protected StoriesSyntaxConverter $storiesConverter,
) {
}
......@@ -59,7 +59,7 @@ class ComponentElementAlter implements TrustedCallbackInterface {
}
$story = $component["stories"][$story_id];
$slots = array_merge($element["#slots"] ?? [], $story["slots"] ?? []);
$element["#slots"] = $this->componentElementAlter->processStoriesSlots($slots);
$element["#slots"] = $this->storiesConverter->convertSlots($slots);
$element["#props"] = array_merge($element["#props"] ?? [], $story["props"] ?? []);
return $element;
}
......
<?php
declare(strict_types=1);
namespace Drupal\ui_patterns_library;
/**
* Convert a component story.
*/
class StoriesSyntaxConverter {
/**
* Process stories slots.
*
* Stories slots have no "#" prefix in render arrays. Let's add them.
*/
public function convertSlots(array $slots): array {
foreach ($slots as $slot_id => $slot) {
if (!is_array($slot)) {
continue;
}
$slots[$slot_id] = $this->convertArray($slot);
}
return $slots;
}
/**
* Convert an array.
*/
protected function convertArray(array $array): array {
if ($this->isRenderArray($array)) {
return $this->convertRenderArray($array);
}
foreach ($array as $index => $value) {
if (!is_array($value)) {
continue;
}
$array[$index] = $this->convertArray($value);
}
return $array;
}
/**
* Convert a render array.
*/
protected function convertRenderArray(array $renderable): array {
foreach ($renderable as $property => $value) {
if (is_array($value)) {
$renderable[$property] = $this->convertArray($value);
}
}
$in_html_tag = (isset($renderable["type"]) && $renderable["type"] === "html_tag");
$html_tag_allowed_render_keys = ["type", "attributes", "tag", "value", "attached"];
foreach ($renderable as $property => $value) {
// html_tag is special.
if ($in_html_tag && !in_array($property, $html_tag_allowed_render_keys)) {
continue;
}
if (str_starts_with($property, "#")) {
continue;
}
$renderable["#" . $property] = $value;
unset($renderable[$property]);
}
return $renderable;
}
/**
* Is the array a render array?
*/
protected function isRenderArray(array $array): bool {
if (array_is_list($array)) {
return FALSE;
}
$render_keys = ["theme", "type", "markup", "plain_text", "#theme", "#type", "#markup", "#plain_text"];
// An array needs one, and only one, of those properties to be a render
// array.
$intersect = array_intersect(array_keys($array), $render_keys);
if (count($intersect) != 1) {
return FALSE;
}
// This property has to be a string value.
if (!is_string($array[$intersect[0]])) {
return FALSE;
}
return TRUE;
}
}
......@@ -3,7 +3,9 @@ services:
class: Drupal\ui_patterns_library\Element\ComponentElementAlter
arguments:
- "@plugin.manager.sdc"
- "@ui_patterns.component_element_alter"
- "@ui_patterns_library.stories_syntax_converter"
ui_patterns_library.stories_syntax_converter:
class: Drupal\ui_patterns_library\StoriesSyntaxConverter
ui_patterns_library.twig.extension:
class: Drupal\ui_patterns_library\Template\TwigExtension
tags:
......
......@@ -127,38 +127,4 @@ class ComponentElementAlter implements TrustedCallbackInterface {
return $element;
}
/**
* Process stories slots.
*
* Stories slots have no "#" prefix in render arrays. Let's add them.
* A bit like UI Patterns 1.x's PatternPreview::getPreviewMarkup()
* This method belongs here because used by both ui_patterns_library and
* ui_patterns_legacy.
*/
public function processStoriesSlots(array $slots): array {
foreach ($slots as $slot_id => $slot) {
if (!is_array($slot)) {
continue;
}
if (array_is_list($slot)) {
$slots[$slot_id] = $this->processStoriesSlots($slot);
}
$slot_keys = array_keys($slot);
$render_keys = ["theme", "type", "markup", "plain_text"];
if (count(array_intersect($slot_keys, $render_keys)) > 0) {
foreach ($slot as $key => $value) {
if (is_array($value)) {
$value = $this->processStoriesSlots($value);
}
if (str_starts_with($key, "#")) {
continue;
}
$slots[$slot_id]["#" . $key] = $value;
unset($slots[$slot_id][$key]);
}
}
}
return $slots;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment