Customizing the search forms

Last modified: January 6, 2010 - 18:17

description

This describes how to override the default SEARCH THEME FORM* layout when using phptemplate based themes and the search.module with Drupal 4.7 and Drupal 5.x.

* The SEARCH THEME FORM is the Search form that that appears in the page header, when enabled. Refer to the NOTES below for overriding the block search form and main page search form.

It may be easier to edit the page.tpl.php file with a customized theme search form layout, but, here is an alternate, more standardized Drupal method to keep it separate.

for use with Drupal 6.x

Step 1) Copy search-block-form.tpl.php from modules/search to the working theme directory & rename it to search-theme-form.tpl.php (Notice the word block has been replaced by theme).

Step 2) Create a template.php file in the theme directory if it doesn't already exist, and add the following code to it:

<?php
/**
* Override or insert PHPTemplate variables into the search_theme_form template.
*
* @param $vars
*   A sequential array of variables to pass to the theme template.
* @param $hook
*   The name of the theme function being called (not used in this case.)
*/
function yourthemename_preprocess_search_theme_form(&$vars, $hook) {
 
// Note that in order to theme a search block you should use
  // 'search_block_form' instead of 'search_theme_form'.

  // Modify elements of the search form
 
$vars['form']['search_theme_form']['#title'] = t('');
 
 
// Set a default value for the search box
 
$vars['form']['search_theme_form']['#value'] = t('Search this Site');
 
 
// Add a custom class to the search box
 
$vars['form']['search_theme_form']['#attributes'] = array('class' => 'NormalTextBox txtSearch',
                                                             
'onfocus' => "if (this.value == 'Search this Site') {this.value = '';}",
                                                             
'onblur' => "if (this.value == '') {this.value = 'Search this Site';}");
 
 
// Change the text on the submit button
  //$vars['form']['submit']['#value'] = t('Go');

  // Rebuild the rendered version (search form only, rest remains unchanged)
 
unset($vars['form']['search_theme_form']['#printed']);
 
$vars['search']['search_theme_form'] = drupal_render($vars['form']['search_theme_form']);

 
$vars['form']['submit']['#type'] = 'image_button';
 
$vars['form']['submit']['#src'] = path_to_theme() . '/images/search.jpg';
   
 
// Rebuild the rendered version (submit button, rest remains unchanged)
 
unset($vars['form']['submit']['#printed']);
 
$vars['search']['submit'] = drupal_render($vars['form']['submit']);

 
// Collect all form elements to make it easier to print the whole form.
 
$vars['search_form'] = implode($vars['search']);
}
?>

The above code basically removes the "Search this Site" message, adds custom classes to the Search textbox, changes the Search button to an image_button, and adds some default text to the textbox, which automatically gets emptied when the textbox gains focus.

Step 3) Clear the Drupal's site cache. Check for the customization to the Search box on the page.

Note that in Drupal 6.x, none of the steps below apply. For Drupl 6.x, the steps above are all the steps necessary. The steps below apply specifically to Drupal 5.x & earlier.

for use with Drupal 5.x & earlier

Step 1 of 2

In a text editor like notepad.exe, create a file called template.php using the the following snippet. If a template.php file already exists, add it to the existing file.

<?php
function phptemplate_search_theme_form($form) {
 
/**
   * This snippet catches the default searchbox and looks for
   * search-theme-form.tpl.php file in the same folder
   * which has the new layout.
   */
 
return _phptemplate_callback('search_theme_form', array('form' => $form), array('search-theme-form'));
}
?>

Upload the new/edited template.php file to the active theme folder.

Step 2 of 2

The template.php snippet catches the default search box layout before it's displayed and looks in the same folder for a search-theme-form.tpl.php file which determines the new layout.

A very simple example of a search-theme-form.tpl.php file maybe illustrated as follows....

for use with Drupal 4.7.x

<label for="edit[search_theme_form_keys]">Search</label>
<input type="text" maxlength="128" name="edit[search_theme_form_keys]" id="edit-search_theme_form_keys"  size="25" value="" title="Enter the terms you wish to search for." class="form-text" />
<input type="submit" name="op" value="Search"  />
<input type="hidden" name="edit[form_id]" id="edit-search-theme-form" value="search_theme_form" />
<input type="hidden" name="edit[form_token]" id="a-unique-id" value="<?php print drupal_get_token('search_theme_form'); ?>" />

Snippet updated and tested with Drupal 4.7.x Feb 24th 2007

for use with Drupal 5.x

<label for="search_theme_form_keys">Custom Search</label>
<input type="text" maxlength="128" name="search_theme_form_keys" id="edit-search_theme_form_keys"  size="25" value="" title="Enter the terms you wish to search for." class="form-text" />
<input type="submit" name="op" value="Search"  />
<input type="hidden" name="form_id" id="edit-search-theme-form" value="search_theme_form" />
<input type="hidden" name="form_token" id="a-unique-id" value="<?php print drupal_get_token('search_theme_form'); ?>" />

Snippet updated and tested with Drupal 5.x Feb 24th 2007

Note: The opening and closing form action tags in search-theme-form.tpl.php are unnecessary. Drupal automatically adds them when rendering the form.

Upload the search-theme-form.tpl.php file to the active theme folder.

example: changing the Search button text

Change the following line in the search-theme-form.tpl.php snippet from this:

<input type="submit" name="op" value="Search"  />

to this:

<input type="submit" src="images/go-button.gif"  name="op" value="GO!"  />

Which changes the button text from "SEARCH" to "GO!". The Value="GO!" field can be edited to any desired text.

example: changing the Search button to an image

This can be done using CSS, but, to change the button to an image using the search-theme-form.tpl.php, change the following line:

from this:
<input type="submit" name="op" value="Search"  />

to this:
<input type="image" src="images/go-button.gif"  name="op" value="Search"  />

This replaces the SUBMIT button with an image called go-button.gif. Edit the path and filename to suit).

Notes

Styling Drupal 5.x search forms

All changes should be tested on a development site before being applied to a production site.

This example involves creating a theme function named mytheme_search_form(). Create the function as follows:

<?php
function mytheme_search_form($form){
  return
_phptemplate_callback('search_theme_form', array('form' => $form));
}
?>

Then create a file in the theme directory named “search_theme_form.tpl.php” and built a custom form.

To add additional search fields to the form, look at node.module, where the function node_form_alter() adds fields to the default form. It didn’t seem necessary to jump through that hoop since the form is mostly hard-coded anyway, so we just add some radio buttons with the name “category” so that we can filter search results by taxonomy. Simple enough. But the search will never actually filter on results. Here we do more hair-pulling and weird debugging. Finally, we go back to the hook_form_alter() functionality, noticing a “processed_keys” key in the $form array. So to make the form honor category search, we add the following things to your template.php file. It’s not clear how much of this is necessary, and we rather suspect we are doing something stupid here, but it seems to work and we are on deadline, so we roll with it.

<?php
function mytheme_search_keys($type = null){
 
$keys = search_get_keys();
     if(
$type){
    
$keys = search_query_insert($keys, 'type', $type);
   }
   if(
$_POST['category']){
 
$keys = search_query_insert($keys, 'category', $_POST['category']);
}
return
$keys;
}

/* Taking over this function so that we can call mytheme_search_validate to do the advanced search.*/

function blog_form_alter($form_id, &#038;$form){
 
if($form_id == 'search_form'){
  
$form['#validate']['mytheme_search_validate'] = array();
   }
}

/* Need to call this to add category to the processed_keys array item so that
* the category actually gets searched in the mini-advanced form we generate
* in mytheme_search_form().
*/

function mytheme_search_validate($form_id, $form_values, &#038;$form){
$keys = $form_values['processed_keys'];
$keys = mytheme_search_keys($form_values['module']);
form_set_value($form['basic']['inline']['processed_keys'], $keys);
}

function
faq_search($op = 'search', $keys){
        switch(
$op){
                case
'name':
                        return
t('content');
                default:
                       
$keys = mytheme_search_keys('faq');
                        return
node_search('search', $keys);
        }
}

function
forum_search($op = 'search', $keys){
        switch(
$op){
                case
'name':
                        return
t('content');
                default:
                       
$keys = mytheme_search_keys('forum');
                        return
node_search('search', $keys);
        }
}

function
blog_search($op = 'search', $keys){
        switch(
$op){
                case
'name':
                        return
t('content');
                default:
                       
$keys = mytheme_search_keys('blog');
                        return
node_search('search', $keys);
        }
}
?>

Now for an explanation. The "mytheme_search_keys()" function is a helper that lets us make sure we are limiting the search to a given node type. It's not clear if that is absolutely necessary, but things seem not to work if we don’t add the “type:” string to the search, so we are leaving it in. Note that this function also looks for $_POST['category'] and adds it to the keys. If we wanted to add other search fields, we would add them here as well. we suppose that since mytheme_search_validate() calls this function to set keys, we could eliminate the extra function and just do the same work in mytheme_search_validate().

Next up, blog_form_alter(). The hook_form_alter() functions are associated with modules, so we chose one we knew our site would be using that didn't have a form_alter hook defined already. It feels kind of hacky, but it seems to work. The idea here is that we need to make the form run a validation function in order to add the keys we’re pulling in from mytheme_search_keys(). It was when we added this code that the category filter actually started working, so it seems to be a crucial bit. The key seems to be adding the keys to the $form['basic']['inline']['processed_keys'] array item, which seems to handle adding the search criteria to the URL and to the search itself.

Finally, we added the three _search() functions, which again feel a little extraneous, but the thing doesn't work unless we add them, so they're staying put for now. All we're doing in these functions is adding the node type to the keys being searched (the search code extracts things like “type:blog” and “category:3″ from the query to do advanced searches) and then executing the node_search() function with the revised $keys value.

So, there you have it, the long way around to having a custom-themed Drupal search form with additional filters based on node type and category.

If you want to customize the

geerlingguy - November 2, 2009 - 20:54

If you want to customize the title of the search form textfield itself, use the following:

  // Add a custom class to the search box
  $vars['form']['search_theme_form']['#attributes'] = array('title' => t('Enter keywords'));

(This will change the title from "Enter the terms you wish to search for"—not even proper English(!)— to "Enter keywords" - you can change that text to whatever you'd like).

Note: you will need to enter this in the section of code included in step 2 above. Happy theming!

__________________
Life is like Drupal: At the end of the day, you wonder how everything's still running!
Work: Midwestern Mac, LLC | Personal: Life is a Prayer.com

translation won't work for

sadist - November 24, 2009 - 23:43

translation won't work for this unless you define a variable for your custom text.

  $search_text = t('Search this Site');

// Modify elements of the search form
  $vars['form']['search_theme_form']['#title'] = '';
 
// Set a default value for the search box
  $vars['form']['search_theme_form']['#value'] = $search_text;
 
// Add a custom class to the search box
  $vars['form']['search_theme_form']['#attributes'] = array('class' => 'NormalTextBox txtSearch',
  'onfocus' => "if (this.value == '$search_text') {this.value = '';}",
  'onblur' => "if (this.value == '') {this.value = '$search_text';}");

...

Drupal 6 troubleshooting

droidenator - December 3, 2009 - 20:22

I tried the method recommended for Drupal 6 and didn't have any luck.

However, I tried using just the function provided in my template.php and replaced "search_theme_form" with "search_block_form" using Find and Replace and it worked great! Hope that helps anyone else out there having problems with this.

thanks for the tips...

khaki - January 14, 2010 - 14:43

thanks for the tips...

Removing Submit button?

wrd - December 11, 2009 - 20:33

How would one go about simply removing the submit button entirely, rather than restyling it?

Edit: nevermind, I just found the $search array...

Works as expected thank you.

edwinallenz - January 20, 2010 - 01:58

Works as expected on drupal 6 thank you.

Removing Submit button

yul63 - February 9, 2010 - 15:20

I was able to do it by replacing the second 'submit' by 'hidden' here:

$vars['search']['submit'] = drupal_render($vars['form']['hidden']);

 
 

Drupal is a registered trademark of Dries Buytaert.