21

I would like to get all nodes that are of my_custom_type type in Drupal 8.

I know I can get all the nodes (of any type) with \Drupal\node\Entity\Node::loadMultiple() and the list of all types by \Drupal\node\Entity\NodeType::loadMultiple().

But how to get only the nodes of given node type?

I really don't want to use specialized module for it (if it's possible), just keep it as simple as possible. I will use the solution in my custom module.

And loading all the nodes with \Drupal\node\Entity\Node::loadMultiple() and then check their type in foreach would hit the performance too much.

39

You can use Drupal::entityQuery() & Node::loadMultiple() to load all the nodes of your given type:

$nids = \Drupal::entityQuery('node')->condition('type','my_custom_type')->execute();
$nodes =  \Drupal\node\Entity\Node::loadMultiple($nids);
  • 1
    Any way to do this generically for any entity type? You would think \Drupal::entityQuery($type)->condition('type',$bundle)>execute(); would work, but sadly no. – liquidcms Apr 14 at 19:47
  • 1
    This answer is specific to node entities. Details will change for other entities. You should ask another question for a general case. – Shawn Conn Apr 14 at 21:04
  • 3
    In OOP code this now is $nids = $this->entityTypeManager->getStorage('node')->getQuery()->condition('type','my_custom_type')->execute();. See drupal.org/node/2849874. – leymannx Oct 9 at 19:19
17

Another way to do this would be using this snippet of code:

$values = [
  'type' => 'page'
];
$nodes = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadByProperties($values);
7

Usually you need published nodes, not all.

$nids = \Drupal::entityQuery('node')
  ->condition('status', 1)
  ->condition('type', 'YOUR-NODE-TYPE')
  ->execute();
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);
7

Its actually very easy,

\Drupal::entityTypeManager()->getStorage('node')
  ->loadByProperties(['type' => 'content_type', 'status' => 1])

If you would like all nodes also unpublished just use:

\Drupal::entityTypeManager()->getStorage('node')
  ->loadByProperties(['type' => 'content_type'])
0

Something that was, at one time, fairly simple to figure out and find documentation for has become quite a bit more confusing and hard to find. This is one of the top search results for this topic, so I want to take the time to post a solution I was able to put together using the new Methods.

My use case is getting a list of published nodes of a certain content type and publishing them to a page as XML to be consumed by a third party.

Here are my declarations. Some of them might be superfluous at this point, but I'm not done upgrading the code as of yet.

<?php
namespace Drupal\my_events_feed\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Component\Serialization;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\Response;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Entity\EntityTypeManager;

Here's the code to just feed the object into the XML

/**
 * Class BuildXmlController.
 */
class BuildXmlController extends ControllerBase {
  /**
   * Builds the xml from an object
   */
  public function build() {
    $my_events = \Drupal::entityTypeManager()
    ->getStorage('node')
    ->loadByProperties([
      'status' => '1',
      'type' => 'submit_an_event',
    ]);

    $thisSerializer = \Drupal::service('serializer');
    $serializedData = $thisSerializer->serialize($my_events, 'xml', ['plugin_id' => 'entity']);

    $response = new Response();
    $response->headers->set('Content-Type', 'text/xml');
    $response->setContent($serializedData);
    return $response;
  }
}

If you need to massage the data, then you'll have to fill an array and make edits there. Of course, you can still serialize a standard library array.

/**
 * Class BuildXmlController.
 */
class BuildXmlController extends ControllerBase {
  /**
   * Builds the xml from an array
   */
  public function build() {

    $my_events = \Drupal::entityTypeManager()
    ->getStorage('node')
    ->loadByProperties([
      'status' => '1',
      'type' => 'submit_an_event',
    ]);

    $nodedata = [];
    if ($my_events) {
      /*
      Get the details of each node and
      put it in an array.
      We have to do this because we need to manipulate the array so that it will spit out exactly the XML we want
       */
      foreach ($my_events as $node) {
        $nodedata[] = $node->toArray();
      }
    }

    foreach ($nodedata as &$nodedata_row) {
      /* LOGIC TO MESS WITH THE ARRAY GOES HERE */
    }

    $thisSerializer = \Drupal::service('serializer');
    $serializedData = $thisSerializer->serialize($nodedata, 'xml', ['plugin_id' => 'entity']);

    $response = new Response();
    $response->headers->set('Content-Type', 'text/xml');
    $response->setContent($serializedData);
    return $response;
  }
}

Hope this helps.

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.