0

Here's my problem (D8):

There's a content type concert. In a paragraph type concerts_list a list of upcoming concerts (concert nodes) is displayed. This concerts_list paragraph is referenced in field_right_column of another paragraph of type 2_columns.

What I want to do is: Hide the right column if there are no upcoming concerts in the concerts paragraph.

My issue is that the outer (parent) paragraph is rendered and preprocessed before the child paragraph and the resulting render array only includes #theme, #paragraph and #cache but not the actual render array used to render the paragraph.

How can I access a child paragraph's render array from the parent? I don't want/need to access the child paragraph's fields since the concerts are no field because the data is simply added to the build array in hook_entity_type view.

When rendering the 2_columns paragraph I need to know whether or not there are any upcoming concerts and if not I'd like to hide the right column.

Is there a better approach to achieving a similar result?

I'd appreciate any hints/tips/...!

Here's the relevant code:

function MODULE_paragraph_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  $bundle = $entity->bundle();
  if ($bundle === 'concerts_list') {
    // Get the max number of concerts we want to display.
    $max_concerts = (int)$entity->get('field_count')->value;
    $build['concerts'] = MODULE_get_upcoming_concersts($max_concerts, 'teaser');
  }
  elseif ($bundle === '2_columns') {
    // Determine whether to show one or 2 columns depending on the number of
    // upcoming concerts in 'concerts_list'.
    // It would also be ok to do that in twig but I'd need to get the data
    // somewhere.
  }
}

function MODULE_get_upcoming_concerts($limit = 0, $view_mode = 'default') {
  $entity_type_manager = \Drupal::entityTypeManager();
  $query = $entity_type_manager
    ->getStorage('node')
    ->getQuery()
    ->condition('type', 'concert')
    ->condition('field_date', strtotime('midnight'), '>')
    ->sort('field_date', 'ASC');

  if ($limit) {
    $query->range(0, $limit);
  }

  $nids = $query->execute();
  if (count($nids) < 1) {
    return [];
  }
  $nodes = $entity_type_manager->getStorage('node')->loadMultiple($nids);
  return $entity_type_manager->getViewBuilder('node')->viewMultiple($nodes, $view_mode);
}
0

I don't understand the code and what you are trying to do, so I answer the question in the title and the last part of the question:

How can i access a child paragraph's render array from the parent? Or is there a better approach to achieving a similar result?

Don't use the render array, use the parent paragraph entity to get the child paragraphs and their field values:

use Drupal\Core\Cache\Cache;

/**
 * Implements hook_ENTITY_TYPE_view() for paragraph entities.
 */
function MODULE_paragraph_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  $bundle = $entity->bundle();
  // check if this is the parent paragraph
  if ($bundle === 'gigs_teaser') {
    foreach ($entity->field_child_paragraphs->referencedEntities() as $paragraph) {
      // get a field value from a child paragraph
      $field_value = $paragraph->field_example->value;
      $build['#cache']['tags'] = Cache::mergeTags($build['#cache']['tags'], $paragraph->getCacheTags());
      ...
    }
  }
}

Node query

I think I understand now the issue more. You ask probably the wrong question, because the "dynamic data from the child paragraph" is in reality not data from this paragraph, but from a node entity query. If you want to access this query data from two places in code, then put the code in a function and store the result in a static variable so that it is not calculated twice.

  • Thanks for your answer! Unfortunately that was not what I wanted to know :) I updated the question to better reflect my issue. – witti Oct 6 '17 at 10:01

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.