Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
28.57% covered (danger)
28.57%
10 / 35
50.00% covered (danger)
50.00%
5 / 10
37.50% covered (danger)
37.50%
3 / 8
33.33% covered (danger)
33.33%
2 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ScaffoldPanel
35.71% covered (danger)
35.71%
10 / 28
50.00% covered (danger)
50.00%
5 / 10
37.50% covered (danger)
37.50%
3 / 8
33.33% covered (danger)
33.33%
2 / 6
28.78
0.00% covered (danger)
0.00%
0 / 1
 keyboardShortcuts
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 defaultConfiguration
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 buildConfigurationForm
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 configurationSummary
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 buildSingleComponent
71.43% covered (warning)
71.43%
5 / 7
60.00% covered (warning)
60.00%
3 / 5
33.33% covered (danger)
33.33%
1 / 3
0.00% covered (danger)
0.00%
0 / 1
5.67
 getLayoutComponentIds
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Plugin\display_builder\Island;
6
7use Drupal\Core\Form\FormStateInterface;
8use Drupal\Core\StringTranslation\TranslatableMarkup;
9use Drupal\display_builder\Attribute\Island;
10use Drupal\display_builder\InstanceInterface;
11use Drupal\display_builder\Island\IslandConfigurationFormInterface;
12use Drupal\display_builder\Island\IslandConfigurationFormTrait;
13use Drupal\display_builder\Island\IslandType;
14use Drupal\display_builder\SourceWithSlotsInterface;
15
16/**
17 * Scaffold island plugin implementation.
18 *
19 * A Wireframe-style hierarchical view (schematic cards, no live preview) -
20 * except for a configurable allowlist of component IDs, rendered with
21 * their real output instead (@see BuilderPanel::buildComponentRealRender()),
22 * so the actual grid/layout nesting is visible at a glance.
23 *
24 * Which components count as "layout" is theme-specific, hence a configurable
25 * list rather than a hardcoded one.
26 */
27#[Island(
28  id: 'scaffold',
29  label: new TranslatableMarkup('Scaffold'),
30  description: new TranslatableMarkup('Hierarchical view like the Wireframe, with configured components (e.g. grid rows) rendered with their real output.'),
31  type: IslandType::View,
32  default_region: 'main',
33  icon: 'grid-3x3-gap',
34)]
35class ScaffoldPanel extends WireframePanelBase implements IslandConfigurationFormInterface {
36
37  use IslandConfigurationFormTrait;
38
39  /**
40   * {@inheritdoc}
41   */
42  public static function keyboardShortcuts(): array {
43    return [
44      'key' => 'g',
45      'help' => t('Show the scaffold'),
46    ];
47  }
48
49  /**
50   * {@inheritdoc}
51   */
52  public function defaultConfiguration(): array {
53    return [
54      'components' => '',
55    ];
56  }
57
58  /**
59   * {@inheritdoc}
60   */
61  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
62    $configuration = $this->getConfiguration();
63
64    $form['components'] = [
65      '#type' => 'textarea',
66      '#title' => $this->t('Render components'),
67      '#description' => $this->t('Component IDs to render with their real output instead of a placeholder. One per line. Example: "ui_suite_bootstrap:grid_row_1". Recommended usage is to set components used as layout/grid.'),
68      '#default_value' => $configuration['components'] ?? '',
69    ];
70
71    return $form;
72  }
73
74  /**
75   * {@inheritdoc}
76   */
77  public function configurationSummary(): array {
78    $count = \count($this->getLayoutComponentIds());
79
80    return [
81      $this->formatPlural($count, '@count component rendered with real output', '@count components rendered with real output'),
82    ];
83  }
84
85  /**
86   * {@inheritdoc}
87   */
88  protected function buildSingleComponent(InstanceInterface $instance, string $node_id, SourceWithSlotsInterface $source, array $data, int $index = 0): ?array {
89    $info = $this->resolveComponentInfo($source, $data, $node_id);
90
91    if ($info === NULL) {
92      return NULL;
93    }
94
95    ['component_id' => $component_id, 'label' => $label, 'instance_id' => $node_id] = $info;
96
97    if (\in_array($component_id, $this->getLayoutComponentIds(), TRUE)) {
98      return $this->buildComponentRealRender($instance, $node_id, $source, $data, $component_id, $label, $index);
99    }
100
101    return parent::buildSingleComponent($instance, $node_id, $source, $data, $index);
102  }
103
104  /**
105   * The configured component IDs to render with their real output.
106   *
107   * @return string[]
108   *   Component IDs, e.g. "ui_suite_bootstrap:grid_row_1".
109   */
110  private function getLayoutComponentIds(): array {
111    $configuration = $this->getConfiguration();
112
113    return \array_filter(\preg_split('/\r\n|\r|\n/', \trim($configuration['components'] ?? '')) ?: []);
114  }
115
116}