Skip to content

Commit 6756e77

Browse files
author
Edouard Cunibil
committed
Fix nested fieldgroups rendering.
1 parent f17c8b2 commit 6756e77

File tree

1 file changed

+66
-17
lines changed

1 file changed

+66
-17
lines changed

modules/ui_patterns_field_group/src/Plugin/field_group/FieldGroupFormatter/PatternFormatter.php

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,70 @@ public static function create(ContainerInterface $container, array $configuratio
9898
* {@inheritdoc}
9999
*/
100100
public function preRender(&$element, $rendering_object) {
101+
$this->preRenderGroup($element, $this->group->group_name, $rendering_object);
102+
}
101103

102-
$fields = [];
103-
$mapping = $this->getSetting('pattern_mapping');
104-
foreach ($mapping as $field) {
105-
$fields[$field['destination']][] = $element[$field['source']];
104+
/**
105+
* Recursive method to build the fieldgroup content.
106+
*
107+
* This method checks if one of the fieldgroup items are a fieldgroup pattern
108+
* themselve. If so, we must build its configuration again and check if this
109+
* fieldgroup doesn't have fieldgroup pattern items itself. (And the story
110+
* keeps going until there are no more people alive on earth).
111+
*
112+
* @param array $element
113+
* Renderable array of the outputed content.
114+
* @param array $group_settings
115+
* Pattern config settings.
116+
*
117+
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
118+
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
119+
*/
120+
protected function preRenderGroup(array &$element, $group_name, array $rendering_object) {
121+
// Do not pre render the group twice.
122+
if (!empty($element['#pattern_pre_rendered'])) {
123+
return;
124+
}
125+
126+
// Load field group settings.
127+
$group = $rendering_object['#fieldgroups'][$group_name];
128+
129+
// Handle groups managed by UI Patterns recursively.
130+
if ($group->format_type == 'pattern_formatter') {
131+
// Move content into their fields.
132+
foreach ($group->format_settings['pattern_mapping'] as $field) {
133+
if ($field['plugin'] == 'fieldgroup') {
134+
$this->preRenderGroup($element[$field['source']], $field['source'], $rendering_object);
135+
}
136+
$element['#fields'][$field['destination']][$field['source']] = $element[$field['source']];
137+
}
138+
139+
// Add render array metadata.
140+
$this->addRenderContext($element, $group->format_settings);
141+
}
142+
// Fallback to default pre_rendering for fieldgroups not managed by UI
143+
// Patterns.
144+
else {
145+
field_group_pre_render($element, $group, $rendering_object);
146+
}
147+
}
148+
149+
/**
150+
* Helper to build the context expected to render the fieldgroup pattern.
151+
*
152+
* @param array $element
153+
* Field data.
154+
* @param array $format_settings
155+
* The pattern format settings.
156+
*/
157+
protected function addRenderContext(array &$element, array $format_settings) {
158+
$element['#id'] = $format_settings['pattern'];
159+
if (!empty($format_settings['pattern_variant'])) {
160+
$element['#variant'] = $format_settings['pattern_variant'];
106161
}
107162

108163
$element['#type'] = 'pattern';
109-
$element['#id'] = $this->getSetting('pattern');
110-
$element['#fields'] = $fields;
111164
$element['#multiple_sources'] = TRUE;
112-
$element['#variant'] = $this->getSetting('pattern_variant');
113165

114166
// Allow default context values to not override those exposed elsewhere.
115167
$element['#context']['type'] = 'field_group';
@@ -119,17 +171,13 @@ public function preRender(&$element, $rendering_object) {
119171
$element['#context']['view_mode'] = $this->configuration['group']->mode;
120172

121173
// Pass current entity to pattern context, if any.
122-
$element['#context']['entity'] = $this->entityFinder->findEntityFromFields($element['#fields']);
123-
}
174+
if (!empty($element['#fields'])) {
175+
$element['#context']['entity'] = $this->entityFinder->findEntityFromFields($element['#fields']);
176+
}
124177

125-
/**
126-
* Get field group name.
127-
*
128-
* @return string
129-
* Field group name.
130-
*/
131-
protected function getFieldGroupName() {
132-
return $this->configuration['group']->group_name;
178+
// Nested groups can be rendered in any order so mark this one as done to
179+
// prevent issues.
180+
$element['#pattern_pre_rendered'] = TRUE;
133181
}
134182

135183
/**
@@ -144,6 +192,7 @@ public function settingsForm() {
144192
$context = [
145193
'entity_type' => $this->configuration['group']->entity_type,
146194
'entity_bundle' => $this->configuration['group']->bundle,
195+
'entity_view_mode' => $this->configuration['group']->mode,
147196
'limit' => $this->configuration['group']->children,
148197
];
149198

0 commit comments

Comments
 (0)