1

So I've got a bit of a unique situation and I'm curious if anyone has any input.

Summary: 

  • I'm trying to figure out how to render 3 nodes from two different sources:
    • 1st Source: A field of type entity reference that allows the user to associate up to 3 nodes of type B (children nodes) with a node of type A (parent node)
    • 2nd Source: An EVA view that is being embedded into a content type's template and pulls in up to 3 nodes that meet the specified criteria

Context:

  • The ultimate goal is to display 3 nodes that meet specific criteria - regardless of their source (i.e. either source 1 or 2 above)
  • Nodes that are set via the field value take precedence over the nodes that are being pulled from the view
  • So if 2 nodes are set via the field values, those two nodes should appear, and then the 3rd node's "spot" should be populated with whatever node that meets the EVA view's criteria, that is not a duplicate of the nodes set via field values, if any such nodes exist. If 1 node is set via the field value, then the view should populate 2 nodes. Etc.

Approach:

Using hook_preprocess_views_view_unformatted__insert_view_name(), I've built out the logic to:

  • Check both sources of content to determine if values exist from each source (Source 1: Entity reference field values set on the parent node, and Source 2: Result nodes coming from a view)
  • Get the node IDs from each relevant source
  • Compare the IDs from both sources to remove any potential duplicates
  • Ensure that nodes set manually via field values take precedence over the view's results
  • Create a storage array ($result_array) with the 3 node IDs that I want to output instead of the view's original results
  • Load the nodes via their IDs

Question:

My question is: Can I use the same preprocess function to output/render the 3 nodes that I've put into the aforementioned storage array? If so, how should I go about doing that? I've tried several different approaches (see below), but I'm not getting the desired results. Would I need to use something like hook_views_query_alter() or hook_views_pre_render() in order to output the correct nodes? If so, should I just pass the variables from one function to the next? Or should I have started in hook_views_query_alter() or hook_views_pre_render() from the start?

As of right now, the view is still outputting the nodes from the view's original query instead of the nodes that I need. As I indicate below in the code, I can load and var_dump() the nodes I want the view to output - but I must be missing something because I cant actually get them to render via the view. The code example below is obviously a bit simplified, but it gets the general point across. 

I have all the node IDs that I need, I'm just having a hard time figuring out how to output them instead of the view's original results. 

Please let me know if you have any questions. Thank you!

EDIT: So to clarify, if less than 3 but more than 0 nodes are set via the entity reference field AND more than 1 node meets the view's criteria, but has not already been set via the entity reference field, than I want to get the 2 (or less) nodes that are being set via entity reference fields and then insert those two nodes into index positions 0 and 1 of the view's render array, and insert the 1st view result into the 2nd index position (i.e. the 3rd item in the array) of the render array - therefore combining the results of the entity reference fields and the view's results.

Code:

/custom/moduleName.module:

 * Implements hook_preprocess_views_view_unformatted().
 */
function MODULENAME_preprocess_views_view_unformatted__insert_view_name(&$variables){
  $view = $variables['view'];

  // $result_array CONTAINS THE 3 NODE IDs THAT I WANT TO RENDER VIA THE VIEW, INSTEAD OF THE VIEW'S ORIGINAL RESULTS.
  $result_array = [1, 2, 3];

  $entities = \Drupal::entityManager()->getStorage('node')->loadMultiple($result_array);

  // SUCCESSFULLY OUTPUTS THE NODES I WANT TO RENDER
  var_dump($entities);

  // ATTEMPT 1:
  $view->result = $entities;

  // ATTEMPT 2:
  foreach ($view->result as $value) {
    // SUCCESSFULLY OUTPUTS THE NODES I WANT TO REPLACE
    var_dump($value->_entity);
    for ($i = 0; $i < count($entities); $i++) {
    // SEEMS TO DO NOTHING
      $value->_entity = $entities[$i];
    }
  }
    // ATTEMPT 3
    for ($i = 0; $i < count($result_array); $i++) {
    ​  $nid = $result_array[$i];
      $entity_type = 'node';
      $view_mode = 'eva_practices_viewpoints';

      $view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);
      $storage = \Drupal::entityTypeManager()->getStorage($entity_type);
      $node = $storage->load($nid);
      $build = $view_builder->view($node, $view_mode);
      $output = render($build);
    }


 // ETC - MULTIPLE OTHER ATTEMPTS THAT ARE LESS SUCCESSFUL

} ```

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.