For a while (earlier in my Drupal career), I was avoiding adding imagefield-attached images to nodes that appeared in my search results, because I remember the first time I tried doing so, I was still quite confused by the way drupal handled search results theming.
Well, after another crack at it, I finally have a nice, performant way of displaying images from nodes added via imagefields (or in drupal 7, image fields) inline with search results, and it didn't require much work at all!
The image above shows inline images for LOLSaints.com, a site which uses Midwestern Mac's Hosted Apache Solr search service to return results quickly and allows faceting, etc. using the excellent Apache Solr Search Integration module. But the technique I'm using works equally well with built-in (but slower) Drupal core search module's results.
Step 1 - Preprocess the search result to get the image data
The first thing you'll need to do is add something along the lines of the following into your theme's template.php file (if there's no template.php file in your current theme, add your own, and just paste in what's below). Change the 'THEMENAME' text to your theme's name:
<?php
/**
* Process variables for search-result.tpl.php.
*
* @see search-result.tpl.php
*/
function THEMENAME_preprocess_search_result(&$variables) {
// Add node object to result, so we can display imagefield images in results.
$n = node_load($variables['result']['node']->nid);
$n && ($variables['node'] = $n);
}
?>
This code basically grabs the node id (nid) of the node being displayed, loads the full node object, and sends the node object over to your search result template, which we'll modify next... (note: if you're displaying tons of nodes per page in your search results, this can be a little taxing. I usually limit it to 10-15 results per page).
Step 2 - Modify search-result.tpl.php to display the image
Next, find the 'search-result.tpl.php' file in drupal core (located in core's modules/search folder), make a copy named exactly the same inside your theme's folder (or inside a 'templates' folder in your theme's folder), and add something like the following wherever you'd like the picture to show up (for my example, I was using an imagefield named 'field_article_image').
<?php if (isset($node->field_article_image[0]['filepath'])): ?>
<span class="search-image"><?php print theme('imagecache', 'search-thumb', $node->field_article_image[0]['filepath']); ?></span>
<?php endif; ?>
For Drupal 6, you can print the image using imagecache at whatever size you want using something like the theme() function I used above. I'll leave it up to the reader to implement the proper theme function for image styles in Drupal 7 :-)
Comments
Great article! Thanks! It might be also good idea to index filepath of the image in Solr index to avoid full node loads.
That would be ideal, but for the purposes of the sites I'm using this on, it's a bit easier to include the full node object; not only is search traffic pretty small, but I sometimes need to switch back to core search (and this method works with core and Solr).
For sites where Solr is more integral, and which have dedicated solr servers, I would definitely store the file path in solr, and get it from the actual search request.
I'm unclear about why you can't just do this with the field display UI in D7. Just add the build mode for search results if the node type in question doesn't have it already, and make the image field visible in this build mode. Use some CSS to make the layout the way you want, and done.
I'm not sure that would work. You could do something similar with cck (or display suite) in drupal 6, but it didn't actually make a difference in the search results.
Hmm I went to manage displays for my content type with the image and set a custom display for the search result. However, nothing was really changed on the actual search results and the image still didn't render.
Thanks for this Jeff. In case someone is wondering what the theme function for D7 would be for image styles.
<?php
theme_image_style(array( 'path' => $node->field_image['und']['0']['uri'], 'style_name' => 'thumbnail'));
?>
Thanks for the snippet!
Instead of using:
$node->field_image['und']['0']['uri']
It would probably be better to use field_get_items() as described on Dave Reid's blog (http://www.davereid.net/content/hlkd7fotw-field-get-items).
Good point, here is an actual example:
// Change NAME to your actual image field name
$image = field_get_items('node', $variables['node'], 'field_NAME');
theme_image_style(array('path' => $image['0']['uri'], 'style_name' => 'thumbnail'));
Ah, perfect. Thx
This gave me some great inspiration for future web updates. Thanks a ton! :D
I am unable to get this working. I'm using drupal 7, and when I enter the preprocess function into my template.php all that shows when I go to search something is a blank white screen. I've changed the THEMENAME to my theme name and followed the directions, but I'm getting nothing. Any suggestions?
For Drupal 7, there are a few other changes needed, like adding the language into the array selecting the imagefield in the template file... You should try using Devel module's dpm() function to inspect the node object or variables array to see exactly what you need to select.
im using d7, while trying to follow ur instruction to get images on search operation im getting the folloing error.
"Fatal error: Call to undefined method stdClass::__get() in /var/www/drupal7t2/themes/bartik/template.php on line 169 "
in my theme i dont have template.php file so i itself create that file in the theme directory and put that coading and replace the theme name instead of THEMENAME. Pls guide me to get the images while serching in d7...
thank you
Would you please share how one than theme the search result by content type? I only want to show images and price for my product content type and a teaser like what you created for my articles so I need separate settings for the content types. Thanks
DS in D6 worked for me initially but after an upgrade it stopped working.
Thanks so much for taking the time to post this blog post as I found it quite helpful with getting my custom image fields to appear in the search results. I ended up using a different approach with the same idea and wanted to share how I solved my problem.
For the project I'm working on I need to display the artist photo with a link to the node on the search results page. I accomplished it by creating a "search-result.tpl.php" file in my theme's directory and added this bit of code to it.
<?php
$path = $result['node']->field_artist_photo['und'][0]['uri'];
print '<a href="' . $url . '">' .theme('image_style', array('style_name' => 'featured_grid', 'path' => $path)) . '</a>';
?>
My field's name is "field_artist_photo" and I'm passing it through the image style preset "featured_grid".
I didn't have to edit my theme's template.php file or anything like that, just the search results .tpl file.
A trick to see the field's information is to add this to your search results .tpl file.
<?php print "<pre>".print_r($result['node']->field_artist_photo, true)."</pre>"; ?>
That prints out all the information that the search results page can access for the field "field_artist_photo". So you can change the field to "body" and it would print out the information about the body. This allows you to see everything that is available to the search results page and works with every field I tried it with.
Hope someone else can find this information useful.
The above comment works with Drupal 7 perfectly without having to add to the template file. Awesome work, thank you. Now if we could only get this working with Apache Solr...
Using the above code now seems to try to get an image into each result and sizes it correctly, however I am getting a broken image icon which suggest that the path to the image is incorrect.
i'm also getting the following error repeated for each search item at the top of the page:
Notice: Undefined property: stdClass::$uc_product_image in include()
I'm guessing a variable name or path is wrong somewhere in your code.
The code is declaring the following path: sites/default/files/styles/product_tmb/public/ which is as it should but is missing any information from the $path variable
$path = $result['node']->uc_product_image['und'][0]['uri'];
which includes my image field uc_product_image this produces the following error:
Undefined property: stdClass::$uc_product_image
This is the correct name for the image field so I am thinking this may have something to do with the preprocessing of the node results.
Yeah; I would say do some inspection with dpm() to see exactly what's in the node object, and check into how you can do preprocessing to make sure you get the proper properties...
I didn't have to use node load to accomplish this.
function mytheme_preprocess_search_result (&$vars) {
$result = $vars['result'];
$vars['node'] = $result['node'];
}
The node was already loaded within search results.
I couldn't have done this without your tutorial though.
Thanks
Jean-Paul
I think a better solution is to store a field containing the the url in solr (not indexed but stored) and retrieve it in the query. this solution allows yo to show result in a site that is not the one that has the node store and you don't need to load a node with each result.
That would be a better idea for sites wanting to get the best performance; fewer database lookups are always better. However, doing things that way requires a bit more Solr-specific work, which is often out of the scope of what many casual module/theme developers would do, so I usually just present the most 'Drupally' solution.
very helpful. thank you for documenting this!
No problem!
thank u it worked..
Worked like a charm! Saved me a bunch of time...
Nice work - thanks!
Worked great....Saved a lot of time too. Cheers
Hi ,
iam new to solr can any one suggest me how to index images in solr-4.6.0 and display it in solr web page .....
i am using windows7,tomcat 7,solr-4.6.0,tika-app jar file...
Thanks In Advance
Hi,
could You write the instruction for D7?
I've tried your code, but no results.
Can you make a related post about the same feature but in Drupal 8?
how we can do same for drupal 8, can you guide me on this.Thanks