1

I am creating a module that will allow editors to display nodes as "cards" using the summary from the node for the card text and a field (field_hero) as a background image to the card, the user can then click-thru to the actual content from the card. The editor can also define, via the layout builder the colour behind the text for the card and also where the text appears (top, left, right, bottom).

If I add several of these cards to a page using the layout builder, all of the cards use the values for position and colour from the last instance placed on the page.

My code block plugin code is:

 public function build() { if ($entity_id = $this->configuration['entity']) { if (($entity = $this->entityStorage->load($entity_id)) && $entity->access('view')) { $render_controller = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId()); $view_mode = isset($this->configuration['view_mode']) ? $this->configuration['view_mode'] : 'default'; if (isset($this->configuration['card_colour'])) { $entity->card_colour = $this->configuration['card_colour']; } if (isset($this->configuration['card_layout'])) { $entity->card_layout = $this->configuration['card_layout']; } return $render_controller->view($entity, $view_mode); } } return []; 

}

And my twig template is (ignore the empty url() in the style attribute):

{% set classes = [ 'node-card', 'card-' ~ node.card_layout|clean_class, node.card_colour|clean_class, 'clearfix' ] %} <article{{ attributes.addClass(classes) }}> <div{{ content_attributes.addClass('bg-img', 'clearfix') }} style="background-image: url()"> <div class="summary"> {{ content.body }} </div> </div> </article> 

1 Answer 1

0

$render_controller->view() invokes hook_ENTITY_TYPE_view() and this would be a better place to add custom values to the entity view.

Although probably not good practice you could get your approach working by cloning the entity before modifying the field values:

$entity = clone $entity; 

In any case you need to adjust caching so that you store for each variant a different cache item in the render cache. For example by adding cache keys to the build array before returning it:

$build = $render_controller->view($entity, $view_mode); if (isset($entity->foo)) { $build['#cache']['keys'][] = $entity->foo; } return $build; 
3
  • Thanks for the answer. The clone method doesn't seem to change anything. I am at a loss to see how I can use the hook method as the values I need to add to the node are held in the layout builder block configuration, which would not be accessible in the hook_ENTITY_TYPE_view. Commented Jun 17, 2019 at 12:59
  • The clone method shows no results because there might be a second problem with the render cache, see the edit. Commented Jun 17, 2019 at 13:52
  • Thanks 4k4 - I had already started down the path of the cache keys, I'm wrestling with cache contexts now! At least I now know where I'm going. Commented Jun 17, 2019 at 15:28

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.