• SJW

    (@whitsey)


    I just can’t get any results to load and I am really tired and am getting nowhere so I thought I would post seeking assistance and hopefully, after a nap, I will have some clarity.

    I have a CPT called service-provider with custom taxonomies region and service-category

    I have created a page called Find a service with slug: find-a-service

    I have created custom page page-find-a-service.php where I load a search form:

    <form role="search" method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
    
        <div class="form-group">
    
            <input type="hidden" name="post_type" value="service-provider" />
            <input type="hidden" name="custom_search" value="true" />
    
            <input type="search" class="search-field form-control" placeholder="<?php echo esc_attr_x( 'Search service providers...', 'placeholder', 'omg' ); ?>" value="<?php echo get_search_query(); ?>" name="s" />
    
    
            <?php
            // Taxonomy filters for region
            $regions = get_terms( array(
                'post_type' => 'service-provider',
                'taxonomy' => 'region',
                'hide_empty' => true,
            ) );
    
            if ( ! empty( $regions ) && ! is_wp_error( $regions ) ) 
            { ?>                        
                <select name="region">
                    <option value="">Select Region</option>
                    <?php foreach ( $regions as $region ) { ?>
                        <option value="<?= $region->slug ?>"><?= $region->name ?></option>
                    <?php } ?>
                </select>
            <?php } ?>
    
            <?php
            // Taxonomy filters for service category
            $service_categories = get_terms( array(
                'post_type' => 'service-provider',
                'taxonomy' => 'service-category',
                'hide_empty' => true,
            ) );
    
            if ( ! empty( $service_categories ) && ! is_wp_error( $service_categories ) ) 
            {?>
                <select name="service-category">
                    <option value="">Select Service Category</option>
                    <?php foreach ( $service_categories as $service_category ) { ?>
                        <option value="<?= $service_category->slug ?>"><?= $service_category->name ?></option>
                    <?php } ?>
                </select>
    
            <?php } ?>
    
            <button type="submit" class="search-submit btn btn-primary"><span class="screen-reader-text"><?php echo _x( 'Search', 'submit button', 'omg' ); ?></span></button>
    
        </div>
    </form>

    I want the search to land back on the same page and have the results load below the search form so I have created the following filter:

    function custom_search_template_redirect() {
    
        if ( is_search() && isset( $_GET['custom_search'] ) && $_GET['custom_search'] === 'true' ) {
    
            include get_stylesheet_directory() . '/page-find-a-service.php'; // Path to your custom search results template
            exit; // Stop further execution
        }
    }
    add_action( 'template_redirect', 'custom_search_template_redirect' );

    however, my code is giving me 0 results – I just can’t get any results to show and I’ve exhausted my will to go on.

    The search code below the search form is as follows:

    <?php
    // Get search parameters
    $search_query = get_search_query();
    $region       = isset( $_GET['region'] ) ? sanitize_text_field( $_GET['region'] ) : '';
    $service_cat  = isset( $_GET['service-category'] ) ? sanitize_text_field( $_GET['service-category'] ) : '';
    
    // Perform custom query based on search parameters
    $args = array(
        'post_type' => 'service-provider',
        's'         => $search_query,
        'tax_query' => array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'region',
                'field'    => 'slug',
                'terms'    => $region,
            ),
            array(
                'taxonomy' => 'service-category',
                'field'    => 'slug',
                'terms'    => $service_cat,
            ),
        ),
    );
    
    $query = new WP_Query( $args ); ?>
    
    <div id="search-results" class="site-content row" role="main">
    
        <div class="col grid_12_of_12">
    
            <?php if ( $query->have_posts() ) : ?>
    
                <header class="page-header">
                    <h1 class="page-title"><?php printf( esc_html__( 'Search Results for: %s', 'omg' ), '<span>&ldquo;' . get_search_query() . '&rdquo;</span>' ); ?></h1>
                </header>
    
                <?php // Start the Loop ?>
                <?php while ( $query->have_posts() ) : $query->the_post(); ?>
    
                    <?php get_template_part( 'content', get_post_type() ); ?>
    
                <?php endwhile; ?>
                <?php wp_reset_postdata(); ?>
    
            <?php else : ?>
    
                <p>Use the search fields above to find services.</p>
    
            <?php endif; // end have_posts() check ?>
    
        </div> <!-- /.col.grid_12_of_12 -->
    
    </div> <!-- /#search-results.site-content.row -->

    Please help me make this work

    • This topic was modified 2 years ago by SJW.
    • This topic was modified 2 years ago by SJW.
Viewing 5 replies - 1 through 5 (of 5 total)
  • Moderator bcworkz

    (@bcworkz)

    While your approach will eventually work once you’ve ironed out the bugs, it’s more complicated than is necessary. Not required, but what I would suggest:

    Drop the template redirect code, the following will make it unnecessary.

    Have your form make a POST request method instead of GET. You’d thus get form data from $_POST or $_REQUEST instead of $_GET.

    Make your form’s action value be empty so the form submission goes back to the same page.

    Add a conditional for your results query that checks if $_SERVER['REQUEST_METHOD'] == 'POST' before doing the query and outputting results.

    Change the search field’s name from “s” to a unique non-WP name. You can still assign the field’s value to “s” in your query, but avoid using default WP query vars when making custom form requests. Then WP is less likely to do something unintended. You cannot then use get_search_query(), instead get the search field value from $_POST.

    If your query fails to work as expected, output $query->request for examination. This is the SQL that WP generates from your query vars. Often the reason nothing is found can be seen here and remedial corrections be made accordingly.

    If you have trouble getting a workable SQL, consider not using the the “s” query var. Default WP search queries can make adding other query criteria difficult. Instead make your own custom LIKE SQL clause that searches only the fields you’re interested in. Add it to your query’s WHERE clause via the “posts_where” filter.

    Thread Starter SJW

    (@whitsey)

    Drop the template redirect code, the following will make it unnecessary.

    Have your form make a POST request method instead of GET. You’d thus get form data from $_POST or $_REQUEST instead of $_GET.

    Originally I was trying to redirect the search results to the already existing archive page and filter there but now I have opted for this solution I will remove this.

    I removed the action so it POSTs to same page but it now gives me a 404 error. I can see in the network tab in developer tools it is going to the exact same page but it is now giving a 404. POSTing to the page gives a 404 but if I highlight the address bar and hit enter it displays s expected… More debugging required here.

    Moderator bcworkz

    (@bcworkz)

    GET requests work but not POST? Could there be some sort of security in place preventing POST requests? .htaccess rule or security plugin?

    Instead of naming your template page-find-a-service.php, determine the page’s ID and use the file name format page-{id}.php. I seem to recall having issues with templates named with page slugs. No idea why, but using ID instead resolved it.

    If any of your form’s field names are the same as WP query vars, using POST with them could cause issues. “s” being the primary suspect.

    Thread Starter SJW

    (@whitsey)

    Thanks, Turns out GET doesn’t work either – it was working to a different page. I can’t submit a form to my search page – no action, action = /find-a-service/, GET, POST all result in 404.

    I changed the action to another page and it works fine – It just appears to be this page for some reason.

    Change the template file to page-{id}.php – same result.

    I changed s to keyword

    I removed the hidden input post_type and now it is working. So passing a “post_type” breaks the search? I guess I’ll just have to hardcode the post type into the query args.

    I have now been able to print the $query->request and it looks odd.

    With no keyword it’s checking if 0 = 1 resulting in 0 rows?

    SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND ( 0 = 1 AND 0 = 1 ) AND ((wp_posts.post_type = 'service-provider' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_status = 'private'))) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10

    But, when I actually enter a keyword (“temp”), it adds a unique random string – is this normal? (still results in 0 rows when there should be 3)

    SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND ( 0 = 1 AND 0 = 1 ) AND (((wp_posts.post_title LIKE '{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}temp{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}') OR (wp_posts.post_excerpt LIKE '{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}temp{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}') OR (wp_posts.post_content LIKE '{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}temp{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}'))) AND ((wp_posts.post_type = 'service-provider' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_status = 'private'))) GROUP BY wp_posts.ID ORDER BY wp_posts.post_title LIKE '{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}temp{2ba466468b9acc648ae20214b766881cae6d618232a794a7f096d20c5b38194c}' DESC, wp_posts.post_date DESC LIMIT 0, 10

    It appears to be this part of the SQL that is producing 0 results – not sure how it is added or how to remove it AND ( 0 = 1 AND 0 = 1 )

    Ok, It’s the tax_query – if no region or cat is selected it passes empty which somehow creates the 0=1.

    • This reply was modified 2 years ago by SJW.
    • This reply was modified 2 years ago by SJW.
    • This reply was modified 2 years ago by SJW.
    Moderator bcworkz

    (@bcworkz)

    Yeah, post_type assigned anything but “page” will prevent access to the page. Conflicts like this is exactly why I recommend not using WP query vars as field names πŸ™‚

    However, patching up the query through “pre_get_posts” will not help. You need to make a new WP_Query object on your template to get the form’s search results. The initial page query needs to work as it normally would.

    When 0 = 1 appears on a WP generated SQL, it means the parser couldn’t make sense of the query vars it was provided. Usually there’s something wrong with how the query was set up. It normally inserts 1 = 1 just because it makes concatenating the rest of the WHERE clause easier, even if there are no other WHERE conditions.

Viewing 5 replies - 1 through 5 (of 5 total)

The topic ‘Creating a CPT search form with results on the same page’ is closed to new replies.