Improve your Apache Solr "More Like This" blocks

The Apache Solr module for Drupal allows you to create ‘More Like This’ blocks that show content related to the currently viewed node. These blocks are very useful as they allow your visitors to serendipitously find similar content to that which they are currently viewing.

Unfortunately, while the default theming for ‘More Like This’ blocks is functional, it can be greatly improved by using view modes.


More graffiti

'More' doesn't have to be plain. Photo: MORE Tribute Wall, by Andy Proctor (creative commons) http://www.flickr.com/photos/andy...


The default theming function for the ‘More Like This’ blocks returns a simple list of linked node titles:

<?php
function theme_apachesolr_search_mlt_recommendation_block($vars) {
 
$docs = $vars['docs'];
 
$links = array();
  foreach (
$docs as $result) {
   
// Suitable for single-site mode. Label is already safe.
   
$links[] = l($result->label, $result->path, array('html' => TRUE));
  }
 
$links = array(
   
'#theme' => 'item_list',
   
'#items' => $links,
  );
  return
render($links);
}
?>

To allow the use of View modes for ‘More Like This’ blocks, we need to override this default theming in a custom module.

First, create a new module, and implement hook_theme_registry_alter() to override the default theme function executed when theme('apachesolr_search_mlt_recommendation_block'...) is called:

<?php
/**
 * Implements hook_theme_registry_alter
 *
 * Update the theme registry so our theme_example_mlt_recommendation_block() is used
 * instead of the default when theme('apachesolr_search_mlt_recommendeation_block'...) is called.
 */
function example_theme_registry_alter(&$theme_registry) {
 
 
$theme_registry['apachesolr_search_mlt_recommendation_block']['function'] = 'theme_example_mlt_recommendation_block';
 
 
// Set the path to this module, so the theme knows where to find the theming function we defined above.
 
$theme_registry['apachesolr_search_mlt_recommendation_block']['theme path'] = drupal_get_path('module', 'example');
}
?>

We then implement our new theming function which accepts the same input as the original theming function:

<?php
/**
 * Our own theming function the theme the MLT blocks to use node views.
 */
function theme_example_mlt_recommendation_block($vars) {
 
$docs = $vars['docs'];
 
$output = array();
 
$nids = array();
 
  foreach (
$docs as $result) { 
   
// Collect the nids from the results.
   
if ($result->entity_type == 'node') {
     
$nids[] = $result->entity_id;
    }
  }
 
  if (!empty(
$nids)) { 
   
// Load the nodes for the 'More Like This' results.
   
$nodes = node_load_multiple($nids); 
 
   
// Format the nodes as with the 'example_mlt_view_mode' view mode.
   
$output = node_view_multiple($nodes, 'example_mlt_view_mode');
  }
 
 
// Return the rendered output.
 
return render($output);
}
?>

As each search snippet is processed, we collect the nid. We then load all the nodes we will need, and pass them to node_view_multiple() for display, with an argument indicating the view mode to use. In this case, we are instructing node_view_multiple() to use the example_mlt_view_mode view mode.

The final task is to implement the new view mode needed for the ‘More Like This’ block. View Modes are a new concept for Drupal 7 which bring much flexibility to your node displays. For a full overview, read Custom Drupal 7 view modes: Different ways to see your content.

A new view mode called ‘More Like This block’ can be created as follows:

<?php
/**
 * Implements hook_entity_info_alter().
 */
function example_entity_info_alter(&$entity_info) {
 
 
// Define a new View mode for 'More Like This blocks'. Ensure the 
  // machine name ('example_mlt_view_mode') matches the one defined in 
  // our call to node_view_multiple() above.
 
$entity_info['node']['view modes']['example_mlt_view_mode'] = array(
   
'label' => t('More Like This block'),
   
'custom settings' => TRUE,
  );
}
 
/**
 * Implements hook_preprocess_node(). 
 *
 * Suggest theme hooks for our new view mode so we can use
 * a template for display. The new view mode can be themed with either
 * node__example_mlt_view_mode.tpl.php or node__<TYPE>__example_mlt_view_mode.tpl.php
 */
function example_preprocess_node(&$vars) {
 
  if (
$vars['view_mode'] == 'example_mlt_view_mode') { 
   
$vars['theme_hook_suggestions'][] = 'node__example_mlt_view_mode';
   
$vars['theme_hook_suggestions'][] = 'node__' . $vars['type'] . '__example_mlt_view_mode';
  }
}
?>

This will provide you with a new view mode to which we can assign fields on each node type.

We want to work with you!