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

Merge branch '3477573-2.0.0-beta4-better-stories' into '2.0.x'

Issue #3477573 by pdureau: Better stories slots processing

See merge request !229
parents b96ad11e 66b87ec0
No related branches found
No related tags found
No related merge requests found
Pipeline #295557 passed with warnings
...@@ -7,8 +7,8 @@ namespace Drupal\ui_patterns_legacy\Element; ...@@ -7,8 +7,8 @@ namespace Drupal\ui_patterns_legacy\Element;
use Drupal\Core\Security\TrustedCallbackInterface; use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Theme\ComponentPluginManager; use Drupal\Core\Theme\ComponentPluginManager;
use Drupal\Core\Theme\ThemeManagerInterface; use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\ui_patterns\Element\ComponentElementAlter as UiPatternsComponentElementAlter;
use Drupal\ui_patterns_legacy\RenderableConverter; use Drupal\ui_patterns_legacy\RenderableConverter;
use Drupal\ui_patterns_library\StoriesSyntaxConverter;
/** /**
* Renders a component story. * Renders a component story.
...@@ -22,13 +22,13 @@ class ComponentElementAlter implements TrustedCallbackInterface { ...@@ -22,13 +22,13 @@ class ComponentElementAlter implements TrustedCallbackInterface {
* The theme manager. * The theme manager.
* @param \Drupal\Core\Theme\ComponentPluginManager $componentPluginManager * @param \Drupal\Core\Theme\ComponentPluginManager $componentPluginManager
* The component plugin manager. * The component plugin manager.
* @param \Drupal\ui_patterns\Element\ComponentElementAlter $componentElementAlter * @param \Drupal\ui_patterns_library\StoriesSyntaxConverter $storiesConverter
* The component element alter. * The stories syntax converter.
*/ */
public function __construct( public function __construct(
protected ThemeManagerInterface $themeManager, protected ThemeManagerInterface $themeManager,
protected ComponentPluginManager $componentPluginManager, protected ComponentPluginManager $componentPluginManager,
protected UiPatternsComponentElementAlter $componentElementAlter, protected StoriesSyntaxConverter $storiesConverter,
) { ) {
} }
...@@ -70,7 +70,7 @@ class ComponentElementAlter implements TrustedCallbackInterface { ...@@ -70,7 +70,7 @@ class ComponentElementAlter implements TrustedCallbackInterface {
return $element; return $element;
} }
$element["#story"] = $this->getStoryId($component["stories"]); $element["#story"] = $this->getStoryId($component["stories"]);
$element["#slots"] = $this->componentElementAlter->processStoriesSlots($element["#slots"] ?? []); $element["#slots"] = $this->storiesConverter->convertSlots($element["#slots"] ?? []);
return $element; return $element;
} }
......
...@@ -5,3 +5,4 @@ core_version_requirement: ^10.3 || ^11 ...@@ -5,3 +5,4 @@ core_version_requirement: ^10.3 || ^11
package: "User interface" package: "User interface"
dependencies: dependencies:
- ui_patterns:ui_patterns - ui_patterns:ui_patterns
- ui_patterns:ui_patterns_library
...@@ -22,4 +22,4 @@ services: ...@@ -22,4 +22,4 @@ services:
arguments: arguments:
- "@theme.manager" - "@theme.manager"
- "@plugin.manager.sdc" - "@plugin.manager.sdc"
- "@ui_patterns.component_element_alter" - "@ui_patterns_library.stories_syntax_converter"
...@@ -6,7 +6,7 @@ namespace Drupal\ui_patterns_library\Element; ...@@ -6,7 +6,7 @@ namespace Drupal\ui_patterns_library\Element;
use Drupal\Core\Security\TrustedCallbackInterface; use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Theme\ComponentPluginManager; use Drupal\Core\Theme\ComponentPluginManager;
use Drupal\ui_patterns\Element\ComponentElementAlter as UiPatternsComponentElementAlter; use Drupal\ui_patterns_library\StoriesSyntaxConverter;
/** /**
* Renders a component story. * Renders a component story.
...@@ -18,12 +18,12 @@ class ComponentElementAlter implements TrustedCallbackInterface { ...@@ -18,12 +18,12 @@ class ComponentElementAlter implements TrustedCallbackInterface {
* *
* @param \Drupal\Core\Theme\ComponentPluginManager $componentPluginManager * @param \Drupal\Core\Theme\ComponentPluginManager $componentPluginManager
* The component plugin manager. * The component plugin manager.
* @param \Drupal\ui_patterns\Element\ComponentElementAlter $componentElementAlter * @param \Drupal\ui_patterns_library\StoriesSyntaxConverter $storiesConverter
* The component element alter. * The stories syntax converter.
*/ */
public function __construct( public function __construct(
protected ComponentPluginManager $componentPluginManager, protected ComponentPluginManager $componentPluginManager,
protected UiPatternsComponentElementAlter $componentElementAlter, protected StoriesSyntaxConverter $storiesConverter,
) { ) {
} }
...@@ -59,7 +59,7 @@ class ComponentElementAlter implements TrustedCallbackInterface { ...@@ -59,7 +59,7 @@ class ComponentElementAlter implements TrustedCallbackInterface {
} }
$story = $component["stories"][$story_id]; $story = $component["stories"][$story_id];
$slots = array_merge($element["#slots"] ?? [], $story["slots"] ?? []); $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"] ?? []); $element["#props"] = array_merge($element["#props"] ?? [], $story["props"] ?? []);
return $element; 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: ...@@ -3,7 +3,9 @@ services:
class: Drupal\ui_patterns_library\Element\ComponentElementAlter class: Drupal\ui_patterns_library\Element\ComponentElementAlter
arguments: arguments:
- "@plugin.manager.sdc" - "@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: ui_patterns_library.twig.extension:
class: Drupal\ui_patterns_library\Template\TwigExtension class: Drupal\ui_patterns_library\Template\TwigExtension
tags: tags:
......
...@@ -127,38 +127,4 @@ class ComponentElementAlter implements TrustedCallbackInterface { ...@@ -127,38 +127,4 @@ class ComponentElementAlter implements TrustedCallbackInterface {
return $element; 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