Home

Spotlightish search result grouping

Jun 28, 2006

Here's a fun, albeit hackish search theme snippet for Drupal.

It takes advantage of the fact that the temporary tables for search stay around, to present results grouped by node type à la Apple Spotlight. Note that it does not simply reformat a single search result page, but regroups results across all pages.

In fact, it's really just a hackish way of doing N separate queries that contain a type:something restriction, one for each node type. To see more results, it presents you with a link to a normal type:something query.

It's a bit inefficient in that the presentational work for the normal results is thrown away (loading nodes, filtering content, extracting a summary). But it's a start ;).

<?php
define
('SEARCH_TYPE_ITEMS', 5);

function
_node_search_result($nid) {
 
$node = node_load($nid);

 
// Get node output (filtered and with module-specific fields).
 
if (node_hook($node, 'view')) {
   
node_invoke($node, 'view', false, false);
  }
  else {
   
$node = node_prepare($node, false);
  }
 
// Allow modules to change $node->body before viewing.
 
node_invoke_nodeapi($node, 'view', false, false);

 
// Fetch comments for snippet
 
$node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
 
// Fetch terms for snippet
 
$node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index');

 
$extra = node_invoke_nodeapi($node, 'search result');

  return array(
'link' => url('node/'. $nid),
              
'type' => node_get_name($node),
              
'title' => $node->title,
              
'user' => theme('username', $node),
              
'date' => $node->changed,
              
'node' => $node,
              
'extra' => $extra,
              
'snippet' => search_excerpt($keys, $node->body));
}

function
phptemplate_search_page($results, $type) {
 
// Only kick in for type-agnostic node searches
 
if ($type == 'node' && !search_query_extract($keys = search_get_keys(), 'type')) {

     
// Get all types used in results
     
$result = db_query("SELECT DISTINCT(n.type) FROM temp_search_results s LEFT JOIN node n ON s.sid = n.nid");
      while (
$node = db_fetch_object($result)) {
       
$types[] = $node->type;
      }

     
$output = '';

      foreach (
$types as $type) {
       
// Fetch results of one particular type from the 2nd search pass results
       
$result = db_query_range("SELECT n.nid FROM temp_search_results s LEFT JOIN node n ON s.sid = n.nid WHERE n.type = '%s'", $type, 0, SEARCH_TYPE_ITEMS + 1);

       
$output .= '<h2>'. check_plain($type) .'</h2>';

       
$i = 0;
       
$output .= '<dl class="search-results">';
        while ((
$node = db_fetch_object($result)) && $i++ < SEARCH_TYPE_ITEMS) {
         
$output .= theme('search_item', _node_search_result($node->nid), $type);
        }
       
$output .= '</dl>';

        if (
db_num_rows($result) > SEARCH_TYPE_ITEMS) {
         
$output .= l(t('More results'), 'search/node/'. search_query_insert(search_get_keys(), 'type', $type));
        }
      }

      return
$output;
    }
  }

 
// Otherwise present the default page
 
return theme_search_page($results, $type);
}
?>

sniplet book

Jun 28, 2006 bertboerland

Steven, is this good enough and copyright free to paste it in the sniplet pages or upload it to cvs?

Err, I suppose

Jun 29, 2006 Steven

But with the disclaimer that it's an ugly inefficient hack?

innefficient hacks.. haha

Jul 14, 2006 Bèr

seven out of ten snippets are hacks like this. 90% of the hardcore theme work means "throwing" old -already loaded- stuff away, or preg-replacing already generated HTML with other HTML. :)

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <b> <dd> <dl> <dt> <i> <li> <ol> <u> <ul> <img> <em> <p> <br> <span> <div> <h2> <h3> <abbr> <small> <table> <tr> <td> <strong> <acronym> <th> <blockquote>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.

More information about formatting options

Recent comments

Images