/** * Builds multiple entities' views; augments entity defaults. * * This function is assigned as a #pre_render callback in ::viewMultiple(). * * By delaying the building of an entity until the #pre_render processing in * drupal_render(), the processing cost of assembling an entity's renderable * array is saved on cache-hit requests. * * @param array $build_list * A renderable array containing build information and context for an * entity view. * * @return array * The updated renderable array. * * @see drupal_render() */ public function buildMultiple(array $build_list) { // Build the view modes and display objects. $view_modes = array(); $langcode = $build_list['#langcode']; $entity_type_key = "#{$this->entityTypeId}"; $view_hook = "{$this->entityTypeId}_view"; // Find the keys for the ContentEntities in the build; Store entities for // rendering by view_mode. $children = Element::children($build_list); foreach ($children as $key) { if (isset($build_list[$key][$entity_type_key])) { $entity = $build_list[$key][$entity_type_key]; if ($entity instanceof FieldableEntityInterface) { $view_modes[$build_list[$key]['#view_mode']][$key] = $entity; } } } // Build content for the displays represented by the entities. foreach ($view_modes as $view_mode => $view_mode_entities) { $displays = EntityViewDisplay::collectRenderDisplays($view_mode_entities, $view_mode); $this->buildComponents($build_list, $view_mode_entities, $displays, $view_mode, $langcode); foreach (array_keys($view_mode_entities) as $key) { // Allow for alterations while building, before rendering. $entity = $build_list[$key][$entity_type_key]; $display = $displays[$entity->bundle()]; $this->moduleHandler()->invokeAll($view_hook, array(&$build_list[$key], $entity, $display, $view_mode, $langcode)); $this->moduleHandler()->invokeAll('entity_view', array(&$build_list[$key], $entity, $display, $view_mode, $langcode)); $this->alterBuild($build_list[$key], $entity, $display, $view_mode, $langcode); // Assign the weights configured in the display. // @todo: Once https://drupal.org/node/1875974 provides the missing API, // only do it for 'extra fields', since other components have been // taken care of in EntityViewDisplay::buildMultiple(). foreach ($display->getComponents() as $name => $options) { if (isset($build_list[$key][$name])) { $build_list[$key][$name]['#weight'] = $options['weight']; } } // Allow modules to modify the render array. $this->moduleHandler()->alter(array($view_hook, 'entity_view'), $build_list[$key], $entity, $display); } } return $build_list; }
/** * {@inheritdoc} */ public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL) { $displays = EntityViewDisplay::collectRenderDisplays($entities, $view_mode); $panelized_entities = []; $fallback_entities = []; foreach ($entities as $id => $entity) { $display = $displays[$entity->bundle()]; if ($this->isPanelizerEnabled($display)) { $panelized_entities[$id] = $entity; } else { $fallback_entities[$id] = $entity; } } $result = []; if (!empty($fallback_entities)) { $result += $this->getFallbackViewBuilder()->viewMultiple($fallback_entities, $view_mode, $langcode); } if (!empty($panelized_entities)) { $result += $this->buildMultiplePanelized($entities, $displays, $view_mode, $langcode); } return $result; }