Unlock the Power of Entity Queries in Drupal 11: A Hands-On Guide to Managing LinkedIn Conversations
Diving into Drupal’s hooks with Entity Queries for LinkedIn Contacts
Drupal continues to be a powerhouse for developers looking to build dynamic, scalable websites. One of its key strengths lies in its flexible hook system, which allows developers to easily manipulate data before it’s displayed on the page. In this article, I’ll show you how to harness the power of Entity Queries in Drupal 11 to display related LinkedIn conversations, helping you manage complex relationships between content types — all without relying on Views!
Whether you're a seasoned developer or just starting out, understanding how to work with Entity Queries in Drupal opens up new possibilities for building custom solutions. If you’ve ever needed to link content dynamically or fetch related data based on custom fields, this post is for you!
Use Case: Fetching LinkedIn Conversations
In this example, I’ll walk you through how I used an Entity Query to fetch and display LinkedIn conversations that are linked to a particular LinkedIn contact. I've set up two content types: linkedin_contacts and linkedin_conversations. The contacts are imported via the Migrate Plus module, and the conversations are stored as a separate content type.
The goal is to display all messages exchanged between a LinkedIn contact and other users, making the interaction history easily accessible. This is achieved by using a custom field (field_url) to establish a relationship between the two content types
Why Not Use a Drupal View?
While you could easily create a Drupal View to display related content, I chose to dive deeper into the flexibility of Drupal’s API by using an Entity Query. This approach allows for greater control over performance, as well as customization of how related content is fetched and displayed. Plus, it gives you a more hands-on understanding of how Drupal's query system works.
Step-by-Step: Implementing the Entity Query
Here’s a high-level overview of how I set up the query:
- Establish a Relationship: I used the field_url field to relate LinkedIn contacts to their conversations. This field stores the LinkedIn URL of the contact, which allows me to fetch all relevant messages sent or received by that contact.
Create an Entity Query: Instead of using Views, I wrote a custom function that performs an Entity Query to search for linkedin_conversations nodes that are either sent to or received by the given LinkedIn contact.
Access Control: I implemented strict access checks to ensure that only users with the proper permissions can view the related content. This ensures your site remains secure and that users only see the content they’re authorized to access.
Dynamic Content Display: Finally, I used Twig to render the results on the page. All related conversations are displayed as an unordered list, with each message fetched directly from the entity query
Code Example: Fetching and Displaying Related Conversations
Here’s a simplified version of the code I used:
php
use Drupal\node\Entity\Node;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Implements hook_preprocess_node() to add an entity query result.
*/
function related_messages_preprocess_node(array &$variables) {
// Check if this is a node of type "contact".
if ($variables['node']->getType() === 'linkedin_contacts') {
$node = $variables['elements']['#node'];
if ($node?->hasField('field_url') && !$node->get('field_url')->isEmpty()) {
// Directly access the URL's value if it exists.
$uri = $node->get('field_url')->first()->uri ?? '';
}
// Perform the entity query to retrieve LinkedIn nodes.
$entity_type_manager = \Drupal::service('entity_type.manager');
$query = $entity_type_manager->getStorage('node')->getQuery()
->condition('status', 1) // Only published nodes
->condition('type', 'linkedin_conversations') // Only nodes of type "linkedin_conversations"
->accessCheck(TRUE); // Enable access checks
// Create an OR condition group for the two fields.
$or_group = $query->orConditionGroup()
->condition('field_sender_profile_url', $uri) // Filter by the sender profile URL
->condition('field_recipent_profile_urls', $uri); // Filter by the recipient profile URLs
// Add the OR condition group to the query.
$query->condition($or_group);
// Sort by creation date in ascending order.
$query->sort('created', 'DESC');
// Execute the query to get node IDs (nids).
$nids = $query->execute();
// Initialize an array to store renderable LinkedIn nodes.
$items = [];
if (!empty($nids)) {
$nodes = Node::loadMultiple($nids);
foreach ($nodes as $node) {
if ($node->access('view')) { // Double-check access on each node.
$items[] = $entity_type_manager
->getViewBuilder('node')
->view($node, 'teaser');
}
}
}
// Add the renderable list of LinkedIn nodes to the page variables.
$variables['content']['linkedin_nodes'] = [
'#theme' => 'item_list',
'#weight' => 999,
'#items' => $items,
'#title' => t('Messages'),
'#cache' => [
'contexts' => ['user.permissions', 'url.path'],
'tags' => ['node_list', 'node:' . $variables['node']->id()],
'max-age' => 3600, // Cache for one hour; adjust as needed.
],
];
}
}
Why Should You Care About This?
Scalability & Performance: By using Entity Queries directly, you can fine-tune the performance of your site, especially when dealing with large amounts of data. Views can be powerful but may not always be the most efficient solution, particularly when working with large datasets.
Better Customization: Entity Queries allow you to build highly customized queries to fetch exactly the content you need, without any unnecessary overhead.
Security: With proper access checks, you ensure that your site remains secure and that users can only access content that they are authorized to view.
Let’s Take Your Drupal Project to the Next Level
Implementing custom Entity Queries like this can dramatically enhance your site’s functionality, whether you're working with LinkedIn data, e-commerce products, or user-generated content. If you’re looking to create a powerful, customized Drupal solution that meets your specific needs, I’d love to help!
Got Questions or Ideas?
Let’s connect and discuss how we can leverage Drupal 11 to build better websites. Whether you're looking to enhance your current site or build something entirely new, I can help you unlock Drupal’s full potential.