0

I am new on Drupal 8 , so i have created a service class which return a list of data, 'articles' (node entities), and I call this service class inside a controller, but no data showing up :

My getArticles() method inside my service:

  public function getArticles(){
    $storage = \Drupal::service('entity_type.manager')->getStorage('node');
    $my_entity_ids = $storage->getQuery()
      ->condition('type', 'article')
      ->condition('status', 1)
      ->execute();
    $my_entities = $storage->loadMultiple($my_entity_ids);
    return $my_entities;
  }

My controller:

public function myPage() {
    $data = \Drupal::service('mymodule.service');
    $dataService = $data->getArticles();
    return $dataService;
  }

My result is a blank white page when I view the path routed to my controller, but I see the following message in my error log:

Recoverable fatal error : Object of class Drupal\node\Entity\Node could not be converted to string dans Drupal\Component\Utility\Xss::filter()'' -----"Warning : strlen() expects parameter 1 to be string, array given dans Drupal\Component\Utility\Unicode::validateUtf8()

Can anyone tell me please why i can't get the articles?

3
  • 2
    You have the articles. They are objects with data. You haven't specified how they should be displayed. Your myPage() method needs to return a render array. What are you trying to display from the articles?
    – sonfd
    Jun 27, 2020 at 23:40
  • Let’s say the title of the articles Jun 28, 2020 at 0:09
  • For example i want to display the title of articles Jun 28, 2020 at 0:16

1 Answer 1

3

Controllers need to return a render array. Let's imagine you process your articles for render in a new method renderMyPage() which you call from myPage() and pass your array of article objects.

If you're displaying multiple fields from the articles, you're best off building and configuring a view mode and then getting the view mode render array as described in this answer.

function renderMyPage($articleObjects) {
  $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');

  $articles = [];
  foreach ($articleObjects as $article) {
    $articles[] = $view_builder->view($article, 'my_view_mode_machine_name');
  }

  return $articles;
}

If you want to render a single field from your article, you can get the render array for a field as described in this answer.

function renderMyPage($articleObjects) {
  $articles = [];
  foreach ($articleObjects as $article) {
    // You can pass a view_mode machine name or
    // an array of field configurations to view().
    $articles[] = $article->title->view();
  }

  return $articles;
}

Alternatively you can build your own render array, say to render the title as an h2.

function renderMyPage($articleObjects) {
  $articles = [];
  foreach ($articleObjects as $article) {
    $articles[] = [
      '#type' => 'html_tag',
      '#html_tag' => 'h2',
      '#value' => $article->title->value,
      // The other methods add cache tags automatically, but we need to add
      // cache tags manually here since we're building the array from scratch.
      '#cache' => [
        'tags' => $article->getCacheTags(),
      ],
    ];
  }

  return $articles;
}

Each of these examples returns an $articles array of renderable contents suitable as a return value from your myPage() method.

4
  • Can i render the body of the article also with the title in the third example? Jun 29, 2020 at 1:13
  • #value' => $article->body->value, i can render it but i need to render both of them not one , Jun 29, 2020 at 1:25
  • Yes, render arrays can be nested so for each article you'd just have to add an array with two render arrays, one for title and one for body. If you're doing more than the one field you really should make a view mode and render it, or, at a minimum, create your own theme hook to render your content. You really don't want to build complex render arrays in PHP here, the UI will do it for you. There's a lot of information out there on each of those subjects. If you're having trouble with that stuff, please feel free to open a new question.
    – sonfd
    Jun 29, 2020 at 1:46
  • okey i will ask a question now about that issue Jun 29, 2020 at 3:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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