Wordpress - Empty search returns home page, how to return not found search page?

Here are 3 ways of fixing this, I advise you use solution 2, but pay attention to the jQuery in solution 1 as a way of avoiding the situation in the first place.

For those wanting more code posted from the question askers theme, this is not a theme issue, this is a general WordPress issue that affects all WordPress sites.

Solution 1

You can find an in depth tutorial on how to fix this here:

http://wpengineer.com/2162/fix-empty-searches/

Today, let’s look at something, that most professionals never see: empty searches. You offer a search input field, and someone hits the submit button unintentionally, without any term entered. The resulting URI looks like this: example.com/?s=. It shows the same content as your front page. In fact, it is the front page.

No one needs that.

Solution 2 (recommended)

Taken froma post by Spitzerg http://wordpress.org/support/topic/blank-search-sends-you-to-the-homepage

Another option is to add a request filter:

add_filter( 'request', 'my_request_filter' );
function my_request_filter( $query_vars ) {
    if( isset( $_GET['s'] ) && empty( $_GET['s'] ) ) {
        $query_vars['s'] = " ";
    }
    return $query_vars;
}

Then if you're reusing the search query in your search form don't forget to trim it so you don't end up with one or more spaces (just to keep things clean, probably won't affect results.

<input type="text" name="s" id="s" value="<?php echo trim( get_search_query() ); ?>"/>

Hope this helps, it seems to be working thus far on my site and doesn't involve changing any of the WP code making upgrades easier.

Solution 3

http://www.warpconduit.net/2011/08/02/fix-redirection-and-error-page-on-empty-wordpress-search/

Similar to solution 2 but not as extensive and slightly different.

    if(!is_admin()){
        add_action('init', 'search_query_fix');
    }
    function search_query_fix(){
        if(isset($_GET['s']) && $_GET['s']==''){
            $_GET['s']=' ';
        }
    }

Create a Page Search.php and paste this code and change your loop with "get_template_part('loop', 'search');

                    <div id="container">
                        <div id="content" role="main">

            <?php if ( have_posts() ) : ?>
                            <h1 class="page-title"><?php printf( __( 'Search Results for: %s', 'mb' ), '<span>' . get_search_query() . '</span>' ); ?></h1>
                            <?php
                            /* Run the loop for the search to output the results.
                             * If you want to overload this in a child theme then include a file
                             * called loop-search.php and that will be used instead.
                             */
                             get_template_part( 'loop', 'search' );
                            ?>
            <?php else : ?>
                            <div id="post-0" class="post no-results not-found">
                                <h2 class="entry-title"><?php _e( 'Nothing Found', 'mb' ); ?></h2>
                                <div class="entry-content">
                                    <p><?php _e( 'Sorry, but nothing matched your search criteria. Please try again with some different keywords.', 'twentyten' ); ?></p>
                                    <?php get_search_form(); ?>
                                </div><!-- .entry-content -->
                            </div><!-- #post-0 -->
            <?php endif; ?>
                        </div><!-- #content -->
                    </div><!-- #container -->

            <?php get_sidebar(); ?>
            <?php get_footer(); ?>

Building on Tom's solution 2 but making sure no posts are returned add a request filter as before:

add_filter( 'request', 'my_request_filter' );
function my_request_filter( $query_vars ) {
    if( isset( $_GET['s'] ) && empty( $_GET['s'] ) ) {
        $query_vars['s'] = " ";
        global $no_search_results;
        $no_search_results = TRUE;
    }
    return $query_vars;
}

But this time set a global variable to say no search results should be returned. Then using a posts_where hook make sure no posts are returned:

add_filter( 'posts_where' , 'posts_where_statement' ); 
function posts_where_statement( $where ) {
    global $no_search_results;
    if($no_search_results) {
        $where .= ' AND 1=0';
    }
    return $where;
}

Tags:

Search