Customize the search results page

Last modified: August 26, 2009 - 02:26

Do you need to change the content shown in the results of the Drupal search? It is imperative to do this in the Drupal way, and it is most helpful to understand the thought process of doing such a procedure. Following is an example of how to customize the Drupal search results from more than just a technical aspect but also from the thought process required. This same thinking can be done when having to customize other components within Drupal framework.

The first step is to find out what is driving the Drupal search. In the modules directory you will see the search folder which is a pretty good indication that this is what drives the Drupal search. Now, open the search module folder to see what is inside and what will be there to customize, keeping in mind that you will not actually be doing any changes to any files in the search module itself.

Inside the search module you will find the standard .info, .install, .module and a .css file. In this case you will be looking at the search.module itself. What you are looking for is something you can hook into or theme. The functions you are looking for are theme_ functions and in the search module you will find theme_search_theme_form, theme_search_block_form, theme_search_item and theme_search_page. You will be able to customize any one of these functions in a way that will not touch the actual Drupal core module. Great!

In this example you are going to change the look of the search result page (or srp to all those seo gurus). We are going to remove the line of info that tells who wrote the node, when it was written, comments etc... From first glance it may be a good assumption that the theme_search_page function is the one to customize from within my own theme. For this example we will use the zen theme that would be located in your /sites/all/themes/zen folder. Here is the theme_search_page which is nicely commented so you can see the parameters, and purpose of this function.

/**
* Format the result page of a search query.
*
* Modules may implement hook_search_page() in order to override this default
* function to display search results. In that case it is expected they provide
* their own themeable functions.
*
* @param $results
*   All search result as returned by hook_search().
* @param $type
*   The type of item found, such as "user" or "node".
*
* @ingroup themeable
*/
function theme_search_page($results, $type) {
  $output = '<dl class="search-results">';

  foreach ($results as $entry) {
    $output .= theme('search_item', $entry, $type);
  }
  $output .= '</dl>';
  $output .= theme('pager', NULL, 10, 0);

  return $output;
}

After looking more closely you will notice that this function calls the theme_search_items function by way of theme('search_item', $entry, $type) so you now see that this is actually the function that you want to manipulate. This function looks like the following:

function theme_search_item($item, $type) {
  $output = ' <dt class="title"><a href="'. check_url($item['link']) .'">'. check_plain($item['title']) .'</a></dt>';
  $info = array();
  if ($item['type']) {
    $info[] = check_plain($item['type']);
  }
  if ($item['user']) {
    $info[] = $item['user'];
  }
  if ($item['date']) {
    $info[] = format_date($item['date'], 'small');
  }
  if (is_array($item['extra'])) {
    $info = array_merge($info, $item['extra']);
  }
  $output .= ' <dd>'. ($item['snippet'] ? '<p>'. $item['snippet'] .'</p>' : '') .'<p class="search-info">'. implode(' - ', $info) .'</p></dd>';
  return $output;
}

So what you will do next is to copy all of the above function directly into my template.php file that is found in the /sites/all/themes/zen folder. The template.php file is what you can use in order to indirectly manipulate core Drupal. Not just for search, but for all core modules. Then change the name of the theme_search_item($item, $type) function to zen_search_item($item, $type). After saving the file, Drupal no longer calls search modules function but now calls your newly created theme zen_search_item function. Simply awsome, and now when you have to do a core drupal update, your changes in the theme will not be over written when a core search module update is performed.

Don't forget to change the name of your template.php function or you may get the following error. "Fatal error: Cannot redeclare theme_search_item() (previously declared in....)" I just saying ... this didn't happen to me ;)

Now, lets get to the really good stuff. Because this new zen_search_item() function is in your theme, you are pretty free to do whatever you need in order to get the results you desire. So, my quick change of removing the extra info mentioned previously can be accomplished by removing the code that contains the extra data that you don't need. Your new function in your template.php file now becomes:

function zen_search_item($item, $type) {
  $output = ' <dt class="title"><a href="'. check_url($item['link']) .'">'. check_plain($item['title']) .'</a></dt>';
  $output .= ' <dd>'. ($item['snippet'] ? '<p>'. $item['snippet'] .'</p>' : '');
  return $output;
}

So, you can see that you removed a lot of info but at this point you can go both ways. You can add content, change the elements or do whatever you desire, without editing core Drupal!

Showing Result Count and Result Range in Drupal 5

butterfi - August 29, 2008 - 23:23

We wanted Google-like search results, e.g. "1-10 of about 100 for 'foo'". Here's what I did:

What was helpful was when I realized that search doesn't return the entire found set, instead it returns: the number of pages in the found set ($pager_total); the page number that you're on ($pager_page_array); and the actual results for that search page ($results). Given those numbers, we can calculate how many search results we have based on the number of returned pages. For result pages that have less then a whole page, like a search with just a few hits, or the last page of a found set of results, we count the $results array for more accurate reporting.

<?php
function theme_search_page($results, $type) {
  global
$pager_page_array, $pager_total;
 
$output = '';
 
//establish page variables
 
$total_pages = $pager_total['0'];
 
$total_page_count = $total_pages - 1;
 
//approx number of results based on page count
 
$approx_results = $total_pages * 10;
 
//calculate range
 
$page_number = $pager_page_array['0'];
 
$start_result = $page_number * 10 + 1;
 
$end_result = $page_number * 10 + 10;
 
//get search term
 
$search_term = arg(2);
 
//remove page numbers and plus signs
 
$search_term = explode('?', $search_term);
 
$search_words = $search_term['0'];
 
//check for a single page of results and count array
 
if($total_pages == '1') {
   
$found_set = count($results);
   
$output .= '<div id="page_results">';
   
$output .= ': '. $start_result .' - '. $found_set .' of '. $found_set .' for "'. $search_words .'"';
   
$output .= '</div>';
  }
  elseif (
$page_number == $total_page_count) {
   
$found_set = count($results);
   
$adjusted_end = $total_page_count * 10 + $found_set;
   
$output .= '<div id="page_results">';
   
$output .= ': '. $start_result .' - '. $adjusted_end .' of '. $adjusted_end .' for "'. $search_words.'"';
   
$output .= '</div>';
  }
  else {
 
$output .= '<div id="page_results">';
 
$output .= ': '. $start_result .' - '. $end_result .' of about '. $approx_results .' for "'. $search_words .'"';
 
$output .= '</div>';
  }
 
$output .= '<div id="search_page">';
 
$output .= '<dl class="search-results">';
  foreach (
$results as $entry) {
   
$output .= theme('search_item', $entry, $type);
  }
 
$output .= '</dl>';
 
$output .= theme('pager', NULL, 10, 0);
 
$output .= '</div>';
  return
$output;
}
?>

Hope that helps!

Here's one that may be a

liberatr - September 25, 2008 - 21:05

Here's one that may be a little simpler:

<?php
function blueprint_search_page($results, $type) {
  global
$pager_page_array, $pager_total;
 
 
$default_results = 10;
 
$count = (count($results) == $default_results)? $default_results: count($results);
 
$first_result = $pager_page_array[0] * $default_results;
 
 
$output = '';
  if((
$pager_total[0] > 1) && ($pager_page_array[0] == $pager_total[0])) {
   
$count_total = sprintf(' of about %d', $default_results * $pager_total[0]);
  }
 
$output .= '<p class="search-count-results">'.sprintf('Showing results %d to %d%s', $first_result + 1, $first_result + $count, $count_total).'</p>';
 
$output .= '<dl class="search-results">';

  foreach (
$results as $entry) {
   
$output .= theme('search_item', $entry, $type);
  }
 
$output .= '</dl>';
 
$output .= theme('pager', NULL, 10, 0);

  return
$output;
}
?>

Ryan Price
Florida Creatives

Both codes work absolutely

wflorian - March 5, 2009 - 10:45

Both codes work absolutely fine with D5. But how can I change number of search results shown on every page? Right now there are shown 10 results per page. I would like to have 20 results on every page.

Changing "$default_results = 10;" to "$default_results = 20;" didn't work...

Getting CSS in Search result page

AP - November 6, 2009 - 19:50

1) Each content page include 'some.php' file which displays dynamic background image according to URL. Search result page is showing CSS code from that 'some.php'. Anyone have any idea, how to get rid of this css code ?

2) How can I have dynamic search result page heading from ' Search Results' to ' Search Results for 'keyword''.

Thanks in Advance..

Drupal 6

davexd - January 12, 2009 - 03:24

I'm having no luck. Would this work the same in Drupal 6?

don't think so

mray - January 16, 2009 - 10:59

I think I followed these steps and end up with a wrong behaviour.
The codesnippet from the template.php always directly shows up on every generated page (and destroying the layout)

It would be awesome if

shevot - March 5, 2009 - 22:09

It would be awesome if someone could give these instructions for Drupal 6. It seems that there are a lot of use here that need because it has been addressed several times with no solution given. Thanks

Total number of search results in Drupal 6

matteusx - April 25, 2009 - 03:12

Similar to the Drupal 5 solutions, this taps into the pager to find the count. However, it looks to me like D6 has a new global $pager_total_items which makes this simple. In my search-results.tpl.php I add:

<?php
 
global $pager_total_items;
?>

and then use:

Your search returned <?php print format_plural($pager_total_items[0], '1 result', '@count results'); ?>.

I didn't need, and didn't figure out, how to show text like "Viewing results 11 to 20 of 99 total." This could be calculated using $pager_page_array and $pager_total like in the Drupal 5 examples, but you'll still have to provide the number of results per page.

More on the global variables here: http://api.drupal.org/api/globals

an error?

avolve - May 16, 2009 - 10:01

I tested this snippet for a site.

Your search returned <?php print format_plural($pager_total_items[0], '1 result', '@count results'); ?>.

I added it to a custom search-result.tpl.php, though no value is returned for the number of results (@count). A search with multiple results and a search with a single results yielded 'Your search returned results'

global?

matteusx - June 1, 2009 - 15:30

Did you make sure to add the global $pager_total_items somewhere before the PHP code? It's the first snippet of code in my earlier post.

repeated...

avolve - June 2, 2009 - 05:01

I had made a error in the code (your snippet works fine). I had not yet posted a follow-up/correction.

Inserting the snippet into the search-result.tpl.php file has the snippet repeated for every search result rather than just at the top.

Oh ok. Yes,

matteusx - June 2, 2009 - 15:22

Oh ok. Yes, search-results.tpl.php is for the entire search results page. search-result.tpl.php is for each search result.

I'm using Drupal 6.x and none

Iulian81 - June 16, 2009 - 14:48

I'm using Drupal 6.x and none of this works. Maybe it is just for the versions 5.x. I think it simply does not recognize the function I insert in Template.php ! I tried to make my search results show thumbnails and to erase the date, time and user. The search.module file even do not contains the function theme_search_items that I understand it must have!

Drupal 6

jeffschuler - June 27, 2009 - 06:36

Customizing search results is even easier in Drupal 6.

Use search-result.tpl.php to override how individual search results are displayed, and search-results.tpl.php for overriding the whole list of results.

Just copy [the source code from] the template file you wish to override -- into a file of the same name in your theme directory, then edit as necessary.

But how to put the header at the top

yakker - July 22, 2009 - 18:47

I'd like to put the <h3> header element above the search form that appears above the search results. I know that Search uses box.tpl.php - that's where the header and content get themed. But the search form gets put above that <h3> element, and I'd like to know how to put it below. Anyone?

Include Header at Top of Search Page Results

d3zign7reak - September 10, 2009 - 19:26

Were you able to include a header at the top of the search results page?

------------------------------------------
Alvin Crespo
Interactive Developer and Designer

Only by using page.tpl.php

yakker - September 10, 2009 - 23:07

You can see the brief discussion here: http://drupal.org/node/478286
The other way you can try, if you don't want to use page.tpl.php to display page headers... (still scratch my head about why I ever wanted to do that), is trying to "trick" it with absolute positioning (below in this thread).

This works but it adds the advance search options too ?

cbz47d - August 21, 2009 - 15:51

I used both the templates to configure my search result as well as the result(s) box. But I am still facing issues:
- I get extra advance search options in the search results in page.tpl.php template ?
- I need the items to be searched in a particular node type ?
- How do I customize the view of search form ?

__
Ashish

Drupal 6.x Search Results Count

pscheffer - July 27, 2009 - 15:17

Eric London has a nice solution for displaying the displaying ### - ### of ### results:

http://thedrupalblog.com/displaying-total-number-results-search-page-and...

Extra Search Form Found with Search Results Page

lthoughton - August 6, 2009 - 16:50

Hi all,

I have a site that contains the search block in the upper right-hand corner of the page. When search results are displayed, there is an extra search form within the results node beginning with "Enter your Keywords" and another search box to do yet another search. The box seems to be coming from the core search module function search_form. I haven't been able to find anything on hiding that extra box. It seems redundant when you have the search block already in place. Is there any way to hide this extra search form from view in the results page? Thanks!

don't think you can get rid of it beyond using style

yakker - August 6, 2009 - 20:10

From what I remember when I dug around, the Search module prints the form directly, between the title and content elements of the page, so unless you hack the core module yourself, there's no way to stop this extra form from printing (could be wrong about this, but that's the conclusion I came to after looking at the search.module code).

But, if you don't mind knowing that the extraneous code is there, you could find a way to hide it with CSS. The form has an id="search-form". Your block level search form should have a different one (I think "search-block-form"). In style.css, add this:

#search-form{
display:none;
}

That would hide the search form EVERY time it appeared in the body of your site. If you wanted to only hit the search page, you should be able to target it specfically by employing the page class that gets written to it by drupal: .page-search. So:

.page-search #search-form{
display:none;
}

Personally, whether it's due to a meaningful attachment to elegant markup, or whether it's because I'm neurotic, I can't stand knowing that <form> is sitting there in the page and just "not" being displayed. ;)

...neurotic, i'm pretty sure.

Addendum: I haven't tried this myself, but I've done similar things to move the comment form around (which suffers from the same sort of issue). Anyone who knows this is a bad idea, please say so! ;)

It worked

lthoughton - August 7, 2009 - 11:40

That was a simple fix to the problem. Thanks! As long as Drupal doesn't break its back calling the form function, I'm happy with hiding it.

There has to be a better way

obrigado - August 17, 2009 - 06:33

There has to be a better way to fix this. Hiding things with CSS doesn't seem sustainable. Maybe a preprocess function somewhere?

A mediocre alternative

obrigado - August 17, 2009 - 07:04

This is just as vulgar conceptually, but at least it stops the HTML before it leaves the server. Drop it into your theme's template_preprocess_page function:

if (arg(0) == 'search') {
$vars['content'] = preg_replace('/<form action="\/search\/node".*<\/form>/s', '', $vars['content']);
}

Still looking for a more 'drupal' way to do this...

html in my results

thetoast - August 27, 2009 - 11:32

I don't know if this is right thread to post this but I can't seem to find anyone else with the same problem. The problem is, my users input their content using the full html filter, when the results of the search is displayed I get html displayed like this
<p><i>Matching Teaching to Learning</i> offers assistance when formulating effective teaching and learning strategies for secondary schools using self-evaluation. It will help

I opened up the search-result.tpl.php file and wrapped the $snippet variable with check_plain and now the results display this
&lt;p&gt;&lt;i&gt;Matching Teaching to <strong>Learning</strong>&lt;/i&gt; offers assistance when formulating effective teaching and <strong>learning</strong> strategies for secondary schools using self-evaluation. It will help

I tried various other functions like strip_tags but with no luck.

My question is, how may I remove the html from the search results?

doh!!!

solved

thetoast - August 27, 2009 - 11:57

I used this is solve that issue <?php print strip_tags((htmlspecialchars_decode($snippet)), '<strong>'); ?>

Keeping the <strong> element in strip_tags will keep the words highlighted (in bold) in the search results that contain the search phrase entered.

doh!!!

Use search-results.tpl.php on no search results

chrispooh - October 13, 2009 - 09:23

Is it possible to use search-results.tpl.php on no search results?

 
 

Drupal is a registered trademark of Dries Buytaert.