Joomla includes component view overrides in templates. This is the ideal technique for restyling and rearranging your search results in Joomla. If you are not familiar with the output overrides, they are explained well in an old post on the Joomla Documentation site. That post discusses Joomla 1.5 explicitly, but the template overrides have changed very little (if at all) between 1.5 and 2.5.
Custom search results require two steps. The first step is to copy the file "default_results.php" from the search component to our template. By positioning it appropriately in the template directory, Joomla will use the template override instead of the component view. Using this technique assures us that a Joomla core update will never replace the updated file. To spell this out, if we make the update to the default_results.php file in the core search component, and Joomla releases an update that affects that very file, the update will overwrite our changes. Since Joomla does not update your custom template directories, you can be certain that your changes will never be overwritten by a Joomla core update. An administrator could still change templates, or remove your file, but that is a whole other issue.
Override the default_results in your template
Specifically, we need to copy the original /components/com_search/views/search/tmpl/default_results.php file to the active template directory /templates/myTemplate/html/com_search/search/default_results.php. For reference, I am using Joomla 1.7.3 (this also works in 2.5) with Phoca Gallery 3.1.5 and Phoca Gallery Search Plugin 3.0.1; the line numbers may be different in 2.5.
I am going to use this Gist at github for these updates. The original revision is the default_results.php file that comes with Joomla. That link is the final, and if you have search results that return with a $result->catid value (like some Phoca components do...), it will display a custom output for those results.
Edit the default_results in your template
In order to test that our template view override is working, try adding a simple header to the top of the results. Update line 13 of default_results.php to include some custom header text (like so). Now execute another search and notice your custom header immediately before the search results display.
Technically, we have a custom search results display. However, that is a pretty worthless customization. I want to make a couple of other updates. First, I want to address what I consider to be a bug. If you keep the Search - Categories plugin enabled, you will notice that category search results feature a nice bottom line that reads, "Created on" with no date. This may be user error, or configuration issues with access control; I have not investigated thoroughly. Either way, it is possible to get this behavior, and I think it is safer to check that a value is available before displaying a string in front of it. To that end, I want to add a couple checks to validate that the '$result->created' value is both set, and not equal to '' (line 36 here).
Running a new search with Category results should display a category result with no "Created on" text. And in fact, any search result without an available created on date, will avoid displaying said text.
Customize results output based on the type of result
Another update I want to make is to customize one type of search result. To do this, I first want to explain that you can achieve this in two different ways. The first technique is to change the plugin, which you achieve by knowing that the view file we are editing outputs specific values ($result->title, $result->section, $result->text, etc.); you simply change those values in the plugin. This is accomplished in a /plugins/search/COMPONENT/COMPONENT.php file - where 'COMPONENT' is something like 'content', 'newsfeeds', or some custom search plugin. A second technique is to add checks in the default_results.php file to determine what kind of search result you have, and disply it uniquely. Each of these techniques has merits depending on the situation. Generally speaking, I would encourage the first technique (changing the plugin.php file) if you only want to achieve changes for a particular type of search result, and if you want more global changes (like removing category, or placing category on the same line as the search result) you should make the change in the template.
For now, we are going to stick with the default_restults.php file, and make an update there. To find a good way to distinguish a type of search result, let us use a good old print_r in our results loop (like this). Now execute a search with multiple types of results (contacts, content, categories, etc.). It gets a little tricky here, you will need to determine an appropriate check for your content. It could be that your content always has the same $result->section value, that the $result->section value always starts/ends with some string, or that your 3rd party component result always has a value $result->someOtherValue - and when that is present you want to do something else.
No matter what your conditional check requires, the code update will be similar. Our code needs to add a conditional to the results loop, that outputs one bit of code for one condition, and another bit of code for all other conditions. I added a conditional check for a $result->catid value here, with a simple placeholder heading. The h2 value in the Gist is really just to confirm that your conditional is working properly. For your actual change, I would start by copying the original result code, and editing it to meet the needs of your update. The actual PHP and html edits are beyond the scope of what I wanted to achieve here, but some ideas would be changing the class for a particular type, so that you can alter the background color, or perhaps removing the section output for some results.
Related to this update, if you simply decide that you want to heavily restyle the search results, you can simply make edits to the default_results.php file in your template, and not worry about any conditionals. For reference, the final version of the custom search results Gist has the print_r removed, and displays only the title and a hardcoded string for search results that meet the condition.
For those of you who do not like to click on links, here is the final revision:
In my next article, we will update search results using the alternate technique, changing the PLUGIN.php file so that it provides alternative data to your view.