David Lohmeyer's Blog

Improving Drupal 8 core search when using multiple content entity searches

Drupal 8 allows you to create multiple search pages which show up as primary tabs on the search page after performing a search. This is cool, but has the limitation of making the user input a search term a second time when they navigate to the other tab.

Suppose you wanted to prepopulate that tab's URL with the current search term. This is possible! So if you tab between the search pages, you can search automatically. In my case I have a search plugin for a "content part" custom entity already made, and a route defined for that search page. I could give more details on how to do that later if requested, but the more interesting bit is being able to change the tab URLs. Here's the code, inside your .theme file:

/**
 * Implements hook_pre_render_HOOK() for menu-local-tasks templates.
 *
 * Changes search tab URLs if you have more than one search page to be able
 * to automatically search the other page when you navigate to it.
 * This snippet assumes two search plugins:
 *  search.plugins:node_search (core)
 *  search.plugins:content_part (custom)
 *
 * This snippet assumes two search routes:
 *  search.view_node_search (core)
 *  search.view_content_part (custom)
 */
function yourtheme_preprocess_menu_local_tasks(&$variables) {
  $keys = \Drupal::request()->query->get('keys');

  if($keys && is_array($variables['primary']['search.plugins:node_search']) && is_array($variables['primary']['search.plugins:content_part'])) {
    // Get the current URL minus query params
    $url  = @( $_SERVER["HTTPS"] != 'on' ) ? 'http://'.$_SERVER["SERVER_NAME"] :  'https://'.$_SERVER["SERVER_NAME"];
    $url .= ( $_SERVER["SERVER_PORT"] !== 80 ) ? ":".$_SERVER["SERVER_PORT"] : "";

    // Make a new URL with query params and assign it to the node search tab link
    $search_node_url = $variables['primary']['search.plugins:node_search']['#link']['url'] =
  \Drupal\Core\Url::fromRoute('search.view_node_search', [], ['query' => ['keys' => $keys]]);
    // Tab links get cached unless we clear this
    $variables['primary']['search.plugins:node_search']['#access']->setCacheMaxAge(1);

    // Make a new URL with query params and assign it to the content part search tab link
    $search_content_part_url = $variables['primary']['search.plugins:content_part']['#link']['url'] =
  \Drupal\Core\Url::fromRoute('search.view_content_part', [], ['query' => ['keys' => $keys]]);
    // Tab links get cached unless we clear this
    $variables['primary']['search.plugins:content_part']['#access']->setCacheMaxAge(1);

  }
  
}

View the Gist on Github.

Related Posts