@@ -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