Jason Is My Name
Jason Is My Name

Reputation: 939

Advanced search using a text input to search through only one category

The goal of this is to use as much core WordPress functionality as possible.

advanced.php - This is the custom search form...

<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">

<input type="hidden" name="search" value="post">

<input id="search-case-study" class="search-case-study" type="text" value="" placeholder="Search..." name="s" />

<input type="submit" id="searchsubmit" value="Search" />

functions.php

// CASE STUDY SEARCH
function advanced_search_query($query) {

    if($query->is_search()) {
        // category terms search.
        $query->set('tax_query', array(
            array(
                'taxonomy' => 'case-study',
                'field' => 'slug'
            )
        ));
    }
    return $query;
}

add_action('pre_get_posts', 'advanced_search_query');
// END CASE STUDY SEARCH

I am also calling the form into the page using:

<?php get_template_part( 'advanced', 'searchform' ); ?>

The form pulls into the page properly.

The form contains the fields I wish to use.

I just need help creating the query within functions.php.

In my case, the slug for the category I wish to search is 'case-study', and it needs to search all the content within that category's blog posts. Returning the link, image, title.

Upvotes: 1

Views: 483

Answers (1)

random_user_name
random_user_name

Reputation: 26180

The tax query doesn't quite work like that. Your desired outcome should actually be somewhat simpler.

See your code, modified (with comments explaining what's going on):

function advanced_search_query( $query ) {
    if( $query->is_search() ) {
        // find the category by slug
        $term = get_category_by_slug( 'case-study' ); 
        // get the category ID
        $id = $term->term_id;
        // set the query argument to search within the category
        $query->set( 'cat', $cat_id );
    }

    // removed "return $query" - $query is passed by reference, so no need to return
}

add_action('pre_get_posts', 'advanced_search_query');

NOTE: This will cause all searches to be limited to this category. Since I'm guessing that's not what you want, may I suggest making the following modifications to your form, as well as the function, so it only limits the search when the search originates with your form:

<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">
    <input type="hidden" name="search" value="post">
    <input id="search-case-study" class="search-case-study" type="text" value="" placeholder="Search..." name="s" />
    <!-- add a hidden input that passes the desired category slug -->
    <input name="cat_slug" value="case-study" />
    <input type="submit" id="searchsubmit" value="Search" />
</form>

Then, update the functions.php function as follows:

function advanced_search_query( $query ) {
    // check if search AND if "cat_slug" input was present
    if( $query->is_search() && ! empty( $_GET['cat_slug'] ) ) {
        // find the category by the slug passed in the input
        $term = get_category_by_slug( $_GET['cat_slug'] ); 
        // defensive check, in case the category could not be found
        if ( ! empty( $term->term_id ) ) {
            // get the category ID
            $cat_id = $term->term_id;
            // set the query argument to search within the category
            $query->set( 'cat', $cat_id );
        }
    }

    // removed "return $query" - $query is passed by reference, so no need to return
}

add_action('pre_get_posts', 'advanced_search_query');

Upvotes: 2

Related Questions