Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.895
diff -u -p -r1.895 node.module
--- modules/node/node.module	19 Oct 2007 10:19:02 -0000	1.895
+++ modules/node/node.module	20 Oct 2007 23:35:04 -0000
@@ -601,7 +601,7 @@ function node_invoke_nodeapi(&$node, $op
       $return = array_merge($return, $result);
     }
     else if (isset($result)) {
-      $return[] = $result;
+      $return[$name] = $result;
     }
   }
   return $return;
Index: modules/search/search.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.css,v
retrieving revision 1.2
diff -u -p -r1.2 search.css
--- modules/search/search.css	27 May 2007 17:57:48 -0000	1.2
+++ modules/search/search.css	20 Oct 2007 23:35:04 -0000
@@ -3,12 +3,6 @@
 .search-form {
   margin-bottom: 1em;
 }
-.search-form p {
-  margin-top: 0;
-  margin-bottom: 0.2em;
-  padding-top: 0;
-  padding-bottom: 0;
-}
 .search-form input {
   margin-top: 0;
   margin-bottom: 0;
Index: modules/search/search.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.module,v
retrieving revision 1.237
diff -u -p -r1.237 search.module
--- modules/search/search.module	20 Oct 2007 21:57:50 -0000	1.237
+++ modules/search/search.module	20 Oct 2007 23:35:04 -0000
@@ -118,17 +118,21 @@ function search_theme() {
   return array(
     'search_theme_form' => array(
       'arguments' => array('form' => NULL),
+      'template' => 'search-theme-form',
     ),
     'search_block_form' => array(
       'arguments' => array('form' => NULL),
+      'template' => 'search-block-form',
     ),
-    'search_item' => array(
-      'arguments' => array('item' => NULL, 'type' => NULL),
+    'search_result' => array(
+      'arguments' => array('result' => NULL, 'type' => NULL),
       'file' => 'search.pages.inc',
+      'template' => 'search-result',
     ),
-    'search_page' => array(
+    'search_results' => array(
       'arguments' => array('results' => NULL, 'type' => NULL),
       'file' => 'search.pages.inc',
+      'template' => 'search-results',
     ),
   );
 }
@@ -940,8 +944,7 @@ function search_form(&$form_state, $acti
  * @see theme_search_box_form().
  */
 function search_box(&$form_state, $form_id) {
-  // Use search_keys instead of keys to avoid ID conflicts with the search block.
-  $form[$form_id .'_keys'] = array(
+  $form[$form_id] = array(
     '#title' => t('Search this site'),
     '#type' => 'textfield',
     '#size' => 15,
@@ -960,23 +963,63 @@ function search_box(&$form_state, $form_
  */
 function search_box_form_submit($form, &$form_state) {
   $form_id = $form['form_id']['#value'];
-  $form_state['redirect'] = 'search/node/'. trim($form_state['values'][$form_id .'_keys']);
+  $form_state['redirect'] = 'search/node/'. trim($form_state['values'][$form_id]);
 }
 
 /**
- * Theme the theme search form.
+ * Process variables for search-theme-form.tpl.php.
  *
- * @ingroup themeable
+ * The $variables array contains the following arguments:
+ * - $form
+ *
+ * @see search-theme-form.tpl.php
  */
-function theme_search_theme_form($form) {
-  return '<div id="search" class="container-inline">'. drupal_render($form) .'</div>';
+function template_preprocess_search_theme_form(&$variables) {
+  $variables['search'] = array();
+  $hidden = array();
+  // Provide variables named after form keys so themers can print each element independently.
+  foreach (element_children($variables['form']) as $key) {
+    $type = $variables['form'][$key]['#type'];
+    if ($type == 'hidden' || $type == 'token') {
+      $hidden[] = drupal_render($variables['form'][$key]);
+    }
+   else {
+      $variables['search'][$key] = drupal_render($variables['form'][$key]);
+    }
+  }
+  // Hidden form elements have no value to themers. No need for separation.
+  $variables['search']['hidden'] = implode($hidden);
+  // Collect all form elements to make it easier to print the whole form.
+  $variables['search_form'] = implode($variables['search']);
 }
 
 /**
- * Theme the block search form.
+ * Process variables for search-block-form.tpl.php.
+ *
+ * The $variables array contains the following arguments:
+ * - $form
  *
- * @ingroup themeable
+ * @see search-block-form.tpl.php
  */
+function template_preprocess_search_block_form(&$variables) {
+  $variables['search'] = array();
+  $hidden = array();
+  // Provide variables named after form keys so themers can print each element independently.
+  foreach (element_children($variables['form']) as $key) {
+    $type = $variables['form'][$key]['#type'];
+    if ($type == 'hidden' || $type == 'token') {
+      $hidden[] = drupal_render($variables['form'][$key]);
+    }
+    else {
+      $variables['search'][$key] = drupal_render($variables['form'][$key]);
+    }
+  }
+  // Hidden form elements have no value to themers. No need for separation.
+  $variables['search']['hidden'] = implode($hidden);
+  // Collect all form elements to make it easier to print the whole form.
+  $variables['search_form'] = implode($variables['search']);
+}
+
 function theme_search_block_form($form) {
   return '<div class="container-inline">'. drupal_render($form) .'</div>';
 }
@@ -994,7 +1037,7 @@ function search_data($keys = NULL, $type
           return module_invoke($type, 'search_page', $results);
         }
         else {
-          return theme('search_page', $results, $type);
+          return theme('search_results', $results, $type);
         }
       }
     }
Index: modules/search/search.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.pages.inc,v
retrieving revision 1.1
diff -u -p -r1.1 search.pages.inc
--- modules/search/search.pages.inc	5 Sep 2007 08:39:57 -0000	1.1
+++ modules/search/search.pages.inc	20 Oct 2007 23:35:04 -0000
@@ -50,63 +50,58 @@ function search_view($type = 'node') {
 }
 
 /**
- * Format the result page of a search query.
+ * Process variables for search-results.tpl.php.
  *
- * 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.
+ * The $variables array contains the following arguments:
+ * - $results
+ * - $type
  *
- * @param $results
- *   All search result as returned by hook_search().
- * @param $type
- *   The type of item found, such as "user" or "node".
- *
- * @ingroup themeable
+ * @see search-results.tpl.php
  */
-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;
+function template_preprocess_search_results(&$variables) {
+  $variables['search_results'] = '';
+  foreach ($variables['results'] as $result) {
+    $variables['search_results'] .= theme('search_result', $result, $variables['type']);
+  }
+  $variables['pager'] = theme('pager', NULL, 10, 0);
+  // Provide alternate search results template.
+  $variables['template_files'][] = 'search-results-'. $variables['type'];
 }
 
-
 /**
- * Format a single result entry of a search query. This function is normally
- * called by theme_search_page() or hook_search_page().
+ * Process variables for search-result.tpl.php.
  *
- * @param $item
- *   A single search result as returned by hook_search(). The result should be
- *   an array with keys "link", "title", "type", "user", "date", and "snippet".
- *   Optionally, "extra" can be an array of extra info to show along with the
- *   result.
- * @param $type
- *   The type of item found, such as "user" or "node".
+ * The $variables array contains the following arguments:
+ * - $result
+ * - $type
  *
- * @ingroup themeable
+ * @see search-result.tpl.php
  */
-function theme_search_item($item, $type) {
-  $output = ' <dt class="title"><a href="'. check_url($item['link']) .'">'. check_plain($item['title']) .'</a></dt>';
+function template_preprocess_search_result(&$variables) {
+  $result = $variables['result'];
+  $variables['url'] = check_url($result['link']);
+  $variables['title'] = check_plain($result['title']);
+
   $info = array();
-  if (!empty($item['type'])) {
-    $info[] = $item['type'];
+  if (!empty($result['type'])) {
+    $info['type'] = $result['type'];
   }
-  if (!empty($item['user'])) {
-    $info[] = $item['user'];
+  if (!empty($result['user'])) {
+    $info['user'] = $result['user'];
   }
-  if (!empty($item['date'])) {
-    $info[] = format_date($item['date'], 'small');
+  if (!empty($result['date'])) {
+    $info['date'] = format_date($result['date'], 'small');
   }
-  if (isset($item['extra']) && is_array($item['extra'])) {
-    $info = array_merge($info, $item['extra']);
-  }
-  $output .= ' <dd>'. (!empty($item['snippet']) ? '<p>'. $item['snippet'] .'</p>' : '') .'<p class="search-info">'. implode(' - ', $info) .'</p></dd>';
-  return $output;
+  if (isset($result['extra']) && is_array($result['extra'])) {
+    $info = array_merge($info, $result['extra']);
+  }
+  // Check for existence. User search does not include snippets.
+  $variables['snippet'] = isset($result['snippet']) ? $result['snippet'] : '';
+  // Provide separated and grouped meta information..
+  $variables['info_split'] = $info;
+  $variables['info'] = implode(' - ', $info);
+  // Provide alternate search result template.
+  $variables['template_files'][] = 'search-result-'. $variables['type'];
 }
 
 /**
@@ -133,4 +128,3 @@ function search_form_submit($form, &$for
   $form_state['redirect'] = 'search/'. $type .'/'. $keys;
   return;
 }
-
