How do you change Drupal 8 search results?

Author picture
Gareth Goodwin profile
Posted by
Gareth Goodwin

I was going going to focus on Drupal 8 configuration management gotchas in this blog - but to my delight(!) I now realise that some of these are being, have been or will be fixed. Which makes my life a lot easier! (As an example, check out one of the issues here).

So instead I’m going to share a quick tip I discovered which focuses on search results in Drupal 8.

The challenge:

By default, Drupal 8 search results displays the last updated date for content, rather than the date the content was actually produced. Our client wanted the blog post to show when they were created, not when when they were last edited.

The reason for this solution is because our client considered potentially confusing for a user to see a search result of a blog post with yesterday’s date, only to click through and find the blog post is from 2015… due to someone fixing a link the day before.

The solution: 

One way this can be done is to use hook_node_search_result, to add additional data (the created date) to the result. However this would be added to the content being displayed, and I just wanted to change what was already there.

It may also have required overriding the search results template file to use the new variable. We also only want it to show up on results that have the date displayed on the node type, like blogs or news articles.

So instead, I used template_preprocess_search_result to change the ‘date’ property to the node created date. This meant no changes to template files, and checks if the date property was already there. The date is stored in the ‘info’ and ‘info_split’ keys - two variables passed to the twig file.

 * Implements hook_preprocess_search_result().

function MODULE_preprocess_search_result(&$variables) {
  // Change the date displayed in search results
  // to be the created date, not the updated date.
  if (isset($variables['info_split']['date'])) {
    $node = $variables['result']['node'];
    $created = \Drupal::service('date.formatter')->format($node->getCreatedTime());
    // The date needs to be updated in two places.
    $variables['info_split']['date'] = $created;
    $variables['info']['#context']['info']['date'] = $created;

The outcome:

Why is this so useful? It meant that the change only needed to happen in one place, rather than two which in my experience is much better for maintainability.

About Gareth Goodwin:

I joined Five Mile in 2010 and I am Lead Drupal Developer. My other expertise is in: PHP, MySQL, JavaScript developer, technical architect, test developer, server administration.