1

I have a controller that passes a list of nodes to a template for rendering. I think I'm missing something simple.

I've tried this with no success:

public function content() {
  $students = $this->getStudents();

  return [
    '#theme' => 'dashboard',
    '#students' => $students,
  ];
}

private function getStudents() {
  $user = $this->currentUser();

  $nids = \Drupal::entityQuery('node')
    ->condition('type','student')
    ->condition('uid', $user->id())
    ->execute();
  $nodes = Node::loadMultiple($nids);
  return $nodes;
}

I have a dashboard theme function:

function dashboard_theme() {
  return [
    'dashboard' => [
    'variables' => ['students' => NULL],
    ],
  ];
}

And a twig template being called:

<ul>
  {% for student in students %}
  <li>{{ student }}</li>
  {% endfor %}
</ul>

This blows up the page with the error Object of type Drupal\node\Entity\Node cannot be printed, which is no surprise, I'm just not sure what/how to send a proper object to twig.

4

Of course as soon as I posted this I figured an answer. This looks a little ugly, but I guess this is the way to go:

public function content() {
  $nodes = $this->getStudents();

  foreach ($nodes as $node) {
    $student = \Drupal::entityTypeManager()
      ->getViewBuilder('node')
      ->view($node);
    $students[] = render($student);
  }

  return [
    '#theme' => 'dashboard',
    '#students' => $students,
  ];
}

Basically, I'm looping through the list of nodes, getting the view builder on each, then calling the render function and adding it to a new array. I had stumbled on this earlier because I was using viewMultiple, which output another array...

If you have a cleaner implementation with viewMultiple let me know.

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.