4

What is the best way to change the number of search results per page when using the core search module?

I have both Drupal 6 and 7 sites that I would like to do this with.

In Drupal 6, the value 10 is hardcoded in do_search().

In Drupal 7, the value 10 is hardcoded in the hooks, eg node_search_execute(), and there isn't a tag added that can uniquely identify the query for altering. The idea has been floated in the issue queue, but as of 2013-01-30, nothing has been committed yet.

In the past I have hacked core and handled upgrades with patch management using the normal methods.

1
  • 1
    ugly as it sounds, what I did in D6 was to create mymodule_search() as a direct copy of node's hook_search() and then made mymodule_do_search() a similar copy but with the number of search results set to mymodule's liking, and then menu altered and so forth a bunch of stuff to gently coerce the users to /search/mymodule/... instead of /search/node/... and yes, all instead of one tiny core hack :(
    – Jimajamma
    Commented Jan 30, 2013 at 21:28

3 Answers 3

1

Overriding the hook implemented from the Node module is not possible because hook_search_execute() is invoked by search_data() using the following code.

  if (module_hook($module, 'search_execute')) {
    $results = module_invoke($module, 'search_execute', $keys, $conditions);
    if (module_hook($module, 'search_page')) {
      return module_invoke($module, 'search_page', $results);
    }
    else {
      return array(
        '#theme' => 'search_results', 
        '#results' => $results, 
        '#module' => $module,
      );
    }
  }

$module is the parameter passed to search_data(). hook_search_execute() is similarly to hook_form() which is invoked for the module implementing the content type, not for every module.

I was looking for a way to alter the query executed to search nodes, and the only way I found is to alter the page callback for search/node. That is the way that requires less code. Otherwise, the only alternative I can think of is implementing a search module to replace the search tab implemented for the Node module.

Since Drupal uses hook_search_info(), but doesn't uses hook_search_info_alter(), and hook_search_info() doesn't return much useful data (at least to help overriding the search query), I think there aren't other alternatives.

1
  • Ah yes thanks, I saw it was a hook and thought module_implements_alter but I see the search module explicitly calls node_search_execute as the search providing module there. Commented Jan 31, 2013 at 6:53
0

A new feature in Drupal 7 is hook_module_implements_alter

You could use that to fork/override the node_search_execute (hook_search_execute) function in your own module.

e.g:

/**
 * Implements hook_module_implements_alter
 */
function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'search_execute') {
    // Sorry node module, no hook_search_execute for you
    unset($implementations['node']);
  }
}

and then implement your own copy

/**
 * Implements hook_search_execute
 * Override core node_search_execute here with custom implementation
 * Basically a clone of node_search_execute, but with limit variable available
 * See mymodule_module_implements_alter
 */
function mymodule_search_execute($keys = NULL, $conditions = NULL) {
  // Add new limit conf variable
  $limit = variable_get('search_result_limit', 10);
  // Build matching conditions
  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('SearchQuery')->extend('PagerDefault');
  $query->join('node', 'n', 'n.nid = i.sid');
  $query
    ->condition('n.status', 1)
    ->addTag('node_access')
    ->searchExpression($keys, 'node');

  // Insert special keywords.
  $query->setOption('type', 'n.type');
  $query->setOption('language', 'n.language');
  if ($query->setOption('term', 'ti.tid')) {
    $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
  }
  // Only continue if the first pass query matches.
  if (!$query->executeFirstPass()) {
    return array();
  }

  // Add the ranking expressions.
  _node_rankings($query);

  // Load results, use limit variable
  $find = $query
    ->limit($limit)
    ->execute();
  $results = array();
  foreach ($find as $item) {
    // Render the node.
    $node = node_load($item->sid);
    $build = node_view($node, 'search_result');
    unset($build['#theme']);
    $node->rendered = drupal_render($build);

    // Fetch comments for snippet.
    $node->rendered .= ' ' . module_invoke('comment', 'node_update_index', $node);

    $extra = module_invoke_all('node_search_result', $node);

    $uri = entity_uri('node', $node);
    $results[] = array(
      'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE))), 
      'type' => check_plain(node_type_get_name($node)), 
      'title' => $node->title, 
      'user' => theme('username', array('account' => $node)), 
      'date' => $node->changed, 
      'node' => $node, 
      'extra' => $extra, 
      'score' => $item->calculated_score, 
      'snippet' => search_excerpt($keys, $node->rendered), 
      'language' => entity_language('node', $node),
    );
  }
  return $results;
}
1
  • Isn't this hook for the same module that implements hook_search_info ? For D6 hook_search, it's clear with the $op.
    – AKS
    Commented Jan 31, 2013 at 5:51
0

To get more than 10 search results on one page in Drupal 7, I have used search_config module. I used it's latest version '7.x-1.1-beta2'.

Once the module is enabled, you can configure the pager limit from Configuration->Search and metadata->Search settings (admin/config/search/settings) under 'ADDITIONAL NODE SEARCH CONFIGURATION' section. You will see 'Results' section there and you can specify pager limit to show more than 10 search results on one page.

Your Answer

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

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