Score:0

Change paragraph object for rendering

mx flag

I have a paragraph type with a node ref field that, if you leave it empty, is supposed to show a random node using some defined logic.

I have the code to do the query and get the node, and ideally I'd want to put it on the paragraph object in some pre-render hook so that the paragraph can render normally using its usual config. Something like this (warning: pseudo-codish):

function mymodule_paragraph_view($build, $paragraph, $display, $view_mode) {
  if (!is_my_paragraph_type($paragraph)) return;

  if (!$paragraph->field_mynoderef->isEmpty()) return;

  $node = getRandomNode();
  $paragraph->set('field_mynoderef', $node);
}

This is setting the value correctly, but it seems it's too late in the render process for it to affect the rendered output (i.e. it doesn't actually show the node). I've also tried doing that on the $build['#paragraph'] object, which contains the same paragraph, with similar results. How can I make this work?

BONUS: How to make it so it caches the output using a time-based configuration (e.g. expire after 60 seconds, so every minute it will show a different node and it won't run the query logic on every request).

Score:0
de flag

You need to build the loaded node into a renderable array, and add it to the $build array.

$node = getRandomNode();

$entity_type = $node->getEntityTypeId();
$view_mode = 'teaser';
$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$build['field_mynoderef'] = $view_builder->view($node, $view_mode);

Your question on caching is not related to this issue and should be separated into a separate question. Drupal Answers is a Q&A site with the format of one question to one answer, and adding the answer to that question would dilute this topic.

mx flag
What if I want to reuse the paragraph display config? (maybe I'm asking for too much, but it seems like it should be possible) This is why I wanted to modify the paragraph object itself and not play with render arrays for the actual node. The idea is to be able to forget about this code, in case the paragraph display config ever changes (e.g. the view mode for the node).
mx flag
Also, is hook_paragraph_view right for this? Because there's also hook_paragraph_view_alter, and of course hook_preprocess_paragraph (the last of which I think is definitely too late in the process).
Jaypan avatar
de flag
I'd use `hook_paragraph_view_alter()` for this. And you should create a new view mode for this display, and assign the fields to that view mode. Then use that view mode instead of 'teaser', and you won't have to worry about anyone changing display, as it will only be used for this view.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.