Customizing the search results

jari - October 2, 2006 - 06:29

I've been trying to find a solution for this problem from the forums couple of days already and can't believe no-one wouldn't have solved it already..

So basically: When I do a search, I get the search results page showing the title of the node, some content of the node including the highlighted search word, and then the information like this on another row:
content type - author - date - X comments - X attachments

How can I customize this output, since I wouldn't like it to show the content type or the attachments, neither the amount of comments?

See search.module source for a themable function

sin - October 2, 2006 - 08:06

Look at function theme_search_item($item, $type) in search.module.
It outputs a single search result.
Override this function in your theme as you need (copy/paste and remove $info[] = $item['type'] and $info = array_merge($info, $item['extra'])).

Thanks sin, that does it,

jari - October 3, 2006 - 06:19

Thanks sin, that does it, great!

Just to clear up the instructions for other people like me that might have to wonder a bit before finally getting it working ;)

Put this in the template.php in theme-folder:

<?php
function phptemplate_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']) {
       
//Don't output the node type
        //$info[] = $item['type'];
   
}
    if (
$item['user']) {
       
$info[] = $item['user'];
    }
    if (
$item['date']) {
       
$info[] = format_date($item['date'], 'small');
    }
    if (
is_array($item['extra'])) {
       
//Don't output the extra information about the node (comments, attachments)
        //$info = array_merge($info, $item['extra']);
   
}
   
$output .= ' <dd>'. ($item['snippet'] ? '<p>'. $item['snippet'] . '</p>' : '') . '<p class="search-info">' . implode(' - ', $info) .'</p></dd>';
    return
$output;
}
?>

Another question that someone might have an answer: How to block some content type completely from the search? The advanced search is disabled and people doing the search can search for example images as well, and images are something that I'd rather not have on the search results..

I don't know the second answer (dig search module)...

sin - October 3, 2006 - 06:54

but have a question: how you disable advanced search? :)

search_config module

jari - October 3, 2006 - 12:14

This works for Smarty, too

markdingemanse - October 18, 2006 - 13:33

Just a note for users of the Smarty Theme Engine: this clean solution works for Smarty too. Just replace phptemplate with smarty in the function name, and place the function in YOURTHEME/smartytemplate.php.

thank you for this info

mrgoltra - May 29, 2007 - 22:23

but what if I want to show post with attached picture and/or video (not the actual image itself)? Maybe add this option? Can anyone suggest how this can be done?

for example I want the search summary output to include

Node Title
Date posted
Location:
Contains: Video
Contains: Image

I am learning as I go. I am a noob.

Thank you,

Mark

what to do for 5.x?

remtheory - October 23, 2007 - 13:36

This is exactly what I need, except for 5.x. Can someone provide a snippet for that?

Thanks!!

works with 5.x too

jari - October 24, 2007 - 06:57

I think it works pretty much the same with 5 - I did the just same thing with 5.3 few days ago:
template.php in the theme folder contains this (well some other stuff also, but I cut out the proprietary stuff).. the $item contains the search result item and the $output contains what will be shown eventually, so mess around with them.

<?php
//Theme the search results
function phptemplate_search_item($item, $type)
{
   
$node_id = $item['node']->nid;
   
//Print the result, if the result is NOT the frontpage, since we don't want the frontpage to appear on results.
   
if($node_id != 59)
    {
       
//Remove author information, since it's always admin in our case
       
unset($item['user']);
       
        if(
$item['type'] != "image")
           
$output = " <dt class=\"title\"><a href=\"" . check_url($item['link']) . "\">" . check_plain($item['title']) . "</a></dt>";
       
       
$info = array();
       
       
//Modify the date depending on the site language defined by i18n-module
       
if ($item['date'])
           
$info[] = custom_date_function_on_our_own_module($item['date'], i18n_get_lang());
       
       
$output .= ' <dd>'. ($item['snippet'] ? $item['snippet'] : '') . '<p class="search-info">' . implode(' - ', $info) .'</p></dd>';
       
       
//If the node type is image, don't print the result. I don't know how to exclude some node types from the search, so this is an ugly way
       
if ($item['type'] == "image")
           
$output = "";
           
        return
$output;
    }
}
?>

totally works

remtheory - October 24, 2007 - 15:56

Sorry I was being a spaz. Thanks for the help!

thanks

Hayakawa - October 2, 2006 - 09:19

thanks

CCK Imagefield

steingard - January 3, 2007 - 13:07

I am developing a product catalogue (not ecommerce) and I need the product's teaser thumbnail image to appear in the search results along with the text keywords.

Anyone have an idea on how I can display the image from a product's teaser CCK imagefield in the search results?

Some hooks and theming functions

sin - January 7, 2007 - 10:40

See
http://api.drupal.org/api/4.7/function/hook_search_item
or
http://api.drupal.org/api/4.7/function/theme_search_item
where you can build custom search result item by adding picture from CCK field, you may be have to parse link url to get node id.
I have no deep knowledge about CCK inner working so can't help further. Please post back your results. Thanks!

At Least It IS Possible

steingard - January 9, 2007 - 12:45

Hey, thanks.

Yeah... I've got a basic understanding of PHP to begin with nevermind the 'inner workings' of CCK... but thank you very much for your insight. I'll read these links you gave me and get together with a programmer friend to see what we can come up with.

Thanks again :)

Node as object, object contins imagefield

steingard - January 23, 2007 - 00:15

I had a friend of mine look at how Drupal outputs item content in an array, and he says it's pretty messy... but after a few hours of trying to weed through the array that turns into an object with an array inside half way through, his solution was as follows:

$imgobject = $item['node'];
$imageurl = $imgobject->field_product_teaser_image;

    $output = '<img src="/' . $imageurl[0]['filepath'] . '" alt="" />'

I put this bit in with the search results snippet as listed above (in template.php) and it worked out nicely. Now I just need to figure out how to grab the ALT information so that it's valid XHTML.

-Cheers

Well done!

sin - January 24, 2007 - 08:43

Try

print_r($imageurl[0]);

to output field array, maybe this will help to find 'alt' tag.

I'm looking to retrieve any

Rhino - November 27, 2007 - 14:49

I'm looking to retrieve any images in a post before the and return that in the search results, but I'm not sure how to adapt this in order to do so. Can anyone help me?

Steingard, I wonder if you

divad - May 14, 2008 - 13:44

Steingard, I wonder if you or someone else might be able to help me figure out a way, with the information you provided above, to amend the code below (which resides in my template.php file) so that I can generate search results with a thumbnail image included. The content I am searching against has a CCK imagefield in it. My code is a copy of what was provided at the top of this thread (see below).

I guess my question is, where do I put the code you supplied to make your image display? Thank you.

function newsflash_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']) {
        //Don't output the node type
        //$info[] = $item['type'];
    }
    if ($item['user']) {
        $info[] = $item['user'];
    }
   if ($item['date']) {
        $info[] = format_date($item['date'], 'small');
    }
    if (is_array($item['extra'])) {
        //Don't output the extra information about the node (comments, attachments)
        //$info = array_merge($info, $item['extra']);
    }
    $output .= ' <dd>'. ($item['snippet'] ? '<p>'.  $item['snippet'] . '</p>' : '') . '<p class="search-info">' . implode(' - ', $info) .'</p></dd>';
    return $output;
}

Something to get you started

jari - May 16, 2008 - 07:48

The following will get also a lot of things about the node that you don't need, so it might use up resources more than you know.

<?php
//This line will load all details of the found node into an object $found_node. The parameter for the node_load() has to be the nid of the search item, most likely $item['nid'], not sure about it though.
$found_node = node_load($node_id);
//The following line appends the CCK fields into the $found_node. If this line doesn't appear, the $found_node doesn't have the imagefield at all. Be aware that you don't need to run it like $found_node = node_invok...... - just as below.
node_invoke_nodeapi($found_node, 'view');
//After these couple of lines the $found_node should include your image, so the following should add the image to your results. Remember to replace the FIELDNAME :)
$output .= $found_node->field_FIELDNAME[0]['view'];
?>

Remember: node_load() and node_invoke_nodeapi() may take resources more than the server can handle, so you should first enable Devel module to see how much the page generation time is for a certain search before applying the image addition. Refresh the same search a few times to get a good assumption on how much time it takes and then make the changes. Then refresh the same search again multiple times and see if the page generation time rises much. If not, it's ok. If it goes up like 1000ms for a full search page, then it might be that you need to find an alternate way that doesn't do so much unneeded things while getting the image data.

Unfortunately nid is not in

pwhite - May 22, 2008 - 13:15

Unfortunately nid is not in the item list

http://api.drupal.org/api/function/theme_search_item/5

I've been trying to find way to theme search results for an ecommerce site with little luck - any ideas?

Update

pwhite - May 22, 2008 - 13:58

I solved the problem in the end by using the faceted search module

http://drupal.org/project/faceted_search

This allows you to use the views module to theme search results to display like products.

Is it not?

jari - May 27, 2008 - 08:00

I'd say this does give the item's nid, though I can test it at the moment to be absolutely sure.

<?php
$node_id
= $item['node']->nid;
?>

my search results display additional node and user information

jenlampton - April 6, 2007 - 02:40

I wanted my search results to include some additional information (from user profiles in my case, not CCK) so I ended up doing a MySQL querry to retrieve the information I needed. I used the phptemplate override of theme_search_item in my template.php. I'm not sure if this is entirely kosher, but it works for me. (Please note that this querry is dependent my DB values, and yours may be different. Check your own via myPhpAdmin before you run this code on your own system!)

<?php

function phptemplate_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[] = $item['type'];
    }
    if (
$item['user']) {
       
// change user log in to user name
       
$JensQuerry = 'SELECT value FROM profile_values pv WHERE fid = 1 AND uid = '.$item['node']->uid;
       
$jensName = db_result(db_query($JensQuerry));
       
$item['user'] = $jensName;
       
$info[] = $item['user'];
    }
    if (
$item['date']) {
       
// use published date instead of updated date
       
$jensDate = $item['node']->created;
       
$item['date'] = $jensDate;
       
// reformat date to site standard
       
if (date('m', $item['date'])== '05'){
             
$item['date'] = date("M d, Y", $item['date']);
            } else {
             
$item['date'] = date("M. d, Y", $item['date']);
            }
       
$info[] = $item['date'];
    }
    if (
is_array($item['extra'])) {
       
$info = array_merge($info, $item['extra']);
    }
   
$output .= ' <dd>'. ($item['snippet'] ? '<p class="snip">'. $item['snippet'] . '</p>' : '') . '<p class="search-info">' . implode(' - ', $info) .'</p></dd>';
    return
$output;
}
?>

I also changed the date and date format in here, but you can ignore that. Good Luck!

*~ current project: www.customerthink.com ~*

Customizing the search results

adonis_raduca - January 7, 2007 - 10:37

I added the search_config module in my Drupal instalation and I disabled the advanced search.
The advanced search dissapear from the search-result page output, but the search box is still there.
How can I remove this search box from the search-result page output? :)

Don't display search block on search pages

mishhh - March 26, 2007 - 14:40

I tell you how I did it in my site:

1. go to themes configuration and remove the search box from your theme
2. go to blocks configuration and enable the "search form" block (then hit "save blocks" button)
3. then go to "search form" block again, hit configure link, and in the section "Show block on specific pages:" add in the Pages textarea the following:

search/*

That's it... no more search form on search pages...
:)

This is what I need, but also for the detailed ad - view

xaler - June 7, 2007 - 08:35

When I look at some ads I found with the search function, I see some Status info and also 'content type - author - date - X comments - X attachments'

I want to hide / delete these details, I think I must follow the same procedure but I cannot find a solution.

I think I must look at the ad module, find the themable details and put those in my theme file (without the content which should not be visible).

Sorry for my poor English, it's hard for me to explain in a foreign language.

Status info lives in $info['extra'] array

sin - June 13, 2007 - 14:03

So no need to theme another function. phptemplate_search_item function, described above, is executed after all modules (including ad) added their extra info to search item. So you have to unset some fields in $info['extra'] array. You may see all of them with print_r($info['extra']) and unset inserting unset($info['extra']['my_example_field']) into phptemplate_search_item function.

Tracking.

Zoologico - November 30, 2007 - 19:29

Thanks.

block some fields

Jenzen - December 13, 2007 - 13:19

Hello,
its possible to block some profile fields?
I had installed "profile-plus-modul" can i edit the profileplus.module to block some fields (for example: name or age)?

Target: if one user write "male" in the search box -> no output of all "male" users

Thanks for helping!!

Greetings from Germany!

Sounds like something I

jari - January 10, 2008 - 08:01

Sounds like something I would be implementing in the future too, so I searched a bit..
I've done it already that for example image nodes are not searchable (removed from the search index), so the hook_update_index() is the key.
You have to implement hook_update_index in your own module and in it somehow you have to find the nodes/users you want to exclude things for and then update the search index with new data (that don't have the name or age anymore).
To get you started: http://drupal.org/node/170605

In wich part of the

enkara - January 28, 2008 - 08:46

In wich part of the page.tpl.php do I have to paste this? It doesn't work for me...

how to show number of items found?

sarabjitsn - February 16, 2008 - 13:26

hi buddies..

the info submitted here is very useful. i need help to show total no of items on the search page.
e.g. Total items found: 158 etc.

Many thanks in advance.

I figured this out by

cam8001 - February 25, 2008 - 03:58

I figured this out by trawling through search.module. Try adding this to one of your theme functions:

<?php
$results_count
= current(db_fetch_array(db_query("SELECT count(*) as results_count FROM temp_search_results")));
?>

Now $results_count will be the total number of items returned by the search, and you can use it in your theme as you see fit.

 
 

Drupal is a registered trademark of Dries Buytaert.