I have a content type with a text field "Person", which assumes up to 3 possible options. I am trying to render a block, where I would display this field with three presons.

if(\Drupal::routeMatch()->getRouteName() == 'entity.node.canonical'){
  $node = Node::load(\Drupal::routeMatch()->getRawParameter('node'));
  if($node->bundle() == "people"){

    // CONTACT
    $render = array();
    if($field = $node->field_contact_person->first()){
      $field = $field->getValue()['value'];
      $render['#markup'] = '<div>'.$field.'</div>';
      $render['#prefix'] = '<div class="block institution"><h3>'.$this->t('Contact person').'</h3>';
      $render['#suffix'] = '</div>';
      $block['#markup'] .= render($render);


The issue is that it fetches only first value. How can I fetch all values and render them in the block?

  • A few remarks: getParameter('node') gets the preloaded node directly from the route. Don't render early, return the unrendered build array. You need to add cache data, or better render the node in a view mode or in a Views block, which both would take care of caching. – 4k4 Sep 4 '18 at 15:11
  • ... as far as cache tags are concerned, but you still need to add a context when loading a node from the current route in a block plugin, unless you get the node via a context definition in your block annotation, see drupal.stackexchange.com/a/199601/47547. – 4k4 Sep 4 '18 at 15:38

Just don't use first() - that gets the first item.

if ($field = $node->field_contact_person) {
  foreach ($field->getValue() as $value) {
    $item_value = $value['value'];

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.