Function Friday #7: send empty searches to the search results page
Every Friday, I’m sharing code snippets that I use to customize WordPress. Feedback/suggestions are always welcome! For more information, check out the first post in the series.
I have a checklist of things to test on every WordPress site I build to make sure I don’t forget something (ever seen a site with a poorly functioning 404 page?). One of the items on the list is to run a search, and once I accidentally did it with an empty search form – just hit enter without filling in any keywords. The URL I was redirected to had a similar query string to the one you get when you do enter a keyword, but it showed the latest blog posts instead of the search results page:
- Enter a keyword (“the”) & hit enter: drollic.ca/?s=the
- Displayed the search results for the keyword “the” (as expected)
- Don’t enter a keyword & hit enter: drollic.ca/?s=
- Displayed the latest blog posts (what?!)
That second URL would return the homepage (if it was set to display the latest posts) or the Posts Page (if it was set to a static page). It turns out this is because a no-keyword search results in is_home being true, rather than is_search as you might expect. I’m not sure why this is – please fill me in if you do!
The code
// Send empty search to results page
function drollic_empty_search( $query ) {
// If 's' request variable is set but empty
if ( isset( $_GET['s'] ) && empty( $_GET['s'] ) ) {
$query->is_search = true;
$query->is_home = false;
}
}
add_action( 'pre_get_posts', 'drollic_empty_search' );
This checks for the presence of that “s” variable in the URL, and if it’s there, it checks whether the variable is empty (i.e. s=, above). If it is set and empty, the function alters the WP query to return true on the conditional tag is_search (a search results page) and false on the conditional tag is_home (the blog homepage).
We’re able to make this change because we’re hooking into the pre_get_posts action, which allows you to alter the WordPress query before it’s executed.
As always, remember to add a unique prefix to your function names (like I’ve done with drollic) to avoid plugin/core conflicts.
Simply adding the code above means that someone performing a keywordless search on your site will now be directed to the search results page, but that page will return all of your content as the results. To take this a step further, add the following code to your search results template (search.php) in your theme:
<?php $keywords = get_search_query();
if ( ! have_posts() || empty( $keywords ) ) { // If there are no posts to display
if ( empty( $keywords ) ) { // If no keyword was entered ?>
<h1>No results</h1>
<p>Please try again with at least one keyword.</p>
<?php } else { // If the keyword returned zero results ?>
<h1>No results for “<?php echo $keywords; ?>”</h1>
<p>Sorry, nothing matched your search criteria. Please try again with some different keywords.</p>
<?php }
} ?>
This code displays a different message depending on whether they searched with no keywords at all, or just with keywords that returned no results. Note that have_posts will be true for no-keyword search results (it does have posts – in fact, it has all of them!), so you need to add the extra empty( $keywords ) condition to make this work.
Where does it go?
The first code snippet can go in a functionality plugin, since it will continue to work regardless of which theme you’re using. The second code snippet belongs in your theme’s search results template. Read more about these two options in the first post in the Function Friday series.
Resources
- isset in the PHP manual
- empty in the PHP manual
- $_GET in the PHP manual
- is_search function in the WordPress Code Reference
- is_home function in the WordPress Code Reference
- pre_get_posts hook in the WordPress Codex
- get_search_query function in the WordPress Code Reference
Leave a Reply