diff --git a/README.txt b/README.txt index 4a62f32..e7c5057 100644 --- a/README.txt +++ b/README.txt @@ -37,8 +37,3 @@ Previous maintainers: * Jeremiah Davis (jerdavis) - http://drupal.org/user/228997 * Mark Fredrickson (mfredrickson) - http://drupal.org/user/31994 --- HINT -- -When you want to display rendered entities that are containing -viewfields inside a view page/panel/block/..., even if the field is not presented inside the -viewmode you are currently displaying inside the view, make sure to change the -ID of the pager. Otherwise the pager will not be shown. diff --git a/viewfield.module b/viewfield.module index 1465f26..67e2176 100644 --- a/viewfield.module +++ b/viewfield.module @@ -102,51 +102,6 @@ function viewfield_field_prepare_view($entity_type, $entities, $field, $instance if ($instances[$entity_id]['settings']['force_default']) { $instance_items = $instances[$entity_id]['default_value']; } - - // Loop through each items to check if the view returns any result or, - // at least, has something to output if no result. - foreach ($instance_items as $delta => &$item) { - // @todo Store name and display separately. - list($view_name, $view_display) = explode('|', $item['vname'], 2); - // @todo Store views arguments serialized. - $args = _viewfield_get_view_args($item['vargs'], $entity_type, $entities[$entity_id]); - - // Get and execute the view here to check for it's results or at least - // an empty value if is set. - $view = views_get_view($view_name, TRUE); - - // Override the view's path to the current path. Otherwise, exposed - // views filters would submit to the front page. - $view->override_path = current_path(); - $view->preview($view_display, $args); - - $item['vdisplay'] = $view_display; - $item['view'] = $view; - - $empty_view = FALSE; - - // When the view has more then one result, we always have something to print. - if (count($view->result) < 2) { - $empty_view = TRUE; - foreach ($view->field as $field_name => $field) { - // Looking for the field field_name array if it is empty. - if (!empty($field->get_value(reset($view->result)))) { - // If it is not empty, we do not have a empty view, - // and we can break the foreach for performance. - $empty_view = FALSE; - break; - } - } - } - - // If we don't have any results or an empty value for this item, unset - // it's delta because is an empty row in fact. - if ($empty_view && empty($view->empty)) { - unset($instance_items[$delta]); - } - } - // Ensure consecutive deltas. - $instance_items = array_values($instance_items); } } @@ -171,13 +126,20 @@ function viewfield_field_formatter_view($entity_type, $entity, $field, $instance switch ($display['type']) { case 'viewfield_default': foreach ($items as $delta => $item) { - $view = $item['view']; - $view_display = $item['vdisplay']; + // @todo Store name and display separately. + list($view_name, $view_display) = explode('|', $item['vname'], 2); + $view = views_get_view($view_name); $elements[$delta] = array( '#type' => 'viewfield', '#access' => $view && $view->access($view_display), '#view' => $view, + '#view_name' => $view_name, + '#view_display' => $view_display, + '#view_arguments' => $item['vargs'], + '#entity_type' => $entity_type, + '#entity_id' => $entity_id, + '#entity' => $entity, ); } break; @@ -190,24 +152,68 @@ function viewfield_field_formatter_view($entity_type, $entity, $field, $instance */ function viewfield_element_info() { $types['viewfield'] = array( + '#pre_render' => array('viewfield_pre_render'), '#theme' => 'viewfield_formatter_default', + '#post_render' => array('viewfield_post_render'), ); return $types; } /** + * #pre_render callback for a viewfield field. + * + * @see viewfield_field_formatter_view() + * @see viewfield_post_render() + */ +function viewfield_pre_render($element) { + $stack = &drupal_static('viewfield_stack', array()); + + // Abort rendering in case the view could not be loaded. + if (empty($element['#view'])) { + // @todo Output an error message? + $element['#printed'] = TRUE; + } + // Abort rendering in case of recursion. + elseif (isset($stack[$element['#entity_type']][$element['#entity_id']])) { + $element['#printed'] = TRUE; + } + // Otherwise, add the rendered entity to the stack to prevent recursion. + else { + $stack[$element['#entity_type']][$element['#entity_id']] = TRUE; + + // Override the view's path to the current path. Otherwise, exposed + // views filters would submit to the front page. + $element['#view']->override_path = current_path(); + + // @todo Store views arguments serialized. + $element['#view_arguments'] = _viewfield_get_view_args($element['#view_arguments'], $element['#entity_type'], $element['#entity']); + } + return $element; +} + +/** + * #post_render callback for a viewfield field. + * + * @see viewfield_pre_render() + * @see viewfield_field_formatter_view() + */ +function viewfield_post_render($content, $element) { + $stack = &drupal_static('viewfield_stack', array()); + + unset($stack[$element['#entity_type']][$element['#entity_id']]); + + return $content; +} + +/** * Return HTML for a view in a field. * * @see views_embed_view() */ function theme_viewfield_formatter_default($variables) { $element = $variables['element']; - $view = $element['#view']; - // No need to reexecute the view here. If other module needs it - // to be reexecuted it must reinvoke $view->preview and store it - // back in the element. - return $view->display_handler->output;; + return $element['#view']->preview($element['#view_display'], $element['#view_arguments']); } /**