0

I'm creating a search widget and for that I use a secondary loop via new WP_Query();

$query = new WP_Query('s=searchTerm');
if ($query->have_posts()){
    while ($query->have_posts()){
        $query->the_post();
        //echo the post
    }
    wp_reset_postdata();
}
else {
    echo 'No results';
    die();
}

The problem is that the search query returns the posts that have the search term in their title or content + the current post/page I'm viewing. How can I avoid that ?

2 Answers 2

2

The title of question is inaccurate. I think you don't want to escape first post, instead you want to exclude current post. You can use the post__not_in argument in WP_Query.

$args = array( 's' => 'searchTerm' );

//Check if we are in a post of any type
if( is_singular() ) {
    $post = get_queried_object();
    $args['post__not_in'] = array( $post->ID )
}

$query = new WP_Query( $args );
if ($query->have_posts()){
    while ($query->have_posts()){
        $query->the_post();
        //echo the post
    }
    wp_reset_postdata();
}

UPDATE

As you are using the code in ajax request, you haven't access to current post data in the ajax action hook. You need to pass the current post ID in the ajax request data.

For example (no tested. just writing here):

//Enqueue the scripts and localize js variables
add_action('wp_enqueue_scripts', 'cyb_scripts');
function cyb_scripts() {

    //register my-script
    wp_register_script( 'my-script', '/url/to/my-sript.js', array('jquery') );

    //enqueue my-sript and dependencies
    wp_enqueue_script('jquery');
    wp_enqueue_script('my-script');

    //Localize script data to use in my-script. Set here the post ID to exlude
    $exclude_post = 0;
    if( is_singurlar() ) {
        $current_post = get_queried_object();
        $exclude_post = $current_post->ID;
    }
    $scriptData = array(
                      'ajaxurl' => admin_url('admin-ajax.php');
                      'exclude_post' => $exclude_post
                     );
     wp_localize_script('my-script', 'my_script_data', $scriptData);

}

//Ajax action hooks
add_action('wp_ajax_nopriv_process_ajax', 'cyb_process_ajax');
add_action('wp_ajax_process_ajax', 'cyb_process_ajax');
function cyb_process_ajax(){

    $args = array( 's' => 'searchTerm' );

    //Check for post to exlude
    if( isset($_GET['exclude_post']) ) {
        $args['post__not_in'] = array( intval( $_GET['exclude_post'] ) );
    }

     $query = new WP_Query( $args );
     //....
     wp_reset_postdata();

}

The javascript:

jQuery(document).ready(function($){

    $.ajax({

        type: "GET",
        url: my_script_data.ajaxurl,
        data: {
            action: "process_ajax",
            exclude_post: my_script_data.exclude_post
        }
    })
    .done( function( response ) {
        //....
    })
    .fail( function( response ){
        //....
    });
});
7
  • You're right. I modified the title. You are right about using post__not_in too. I tried that before asking here, but the thing is that the $post->ID is empty . I tried even GLOBAL $post; and then $post->ID but is empty. I'm in function.php. Aug 31, 2014 at 12:31
  • on an ajax callback function . add_action('wp_ajax_nopriv_do_smth', 'do_smth'); add_action('wp_ajax_do_smth', 'do_smth'); function do_smth() {//code} Maybe this is the problem ? Aug 31, 2014 at 12:45
  • get_the_ID() is better than using global. If ID is not available then it's too early or something is messing it up.
    – Rarst
    Aug 31, 2014 at 14:12
  • In the code I posted I don't use get_the_ID nor global $post;. I use get_queried_object() and is_singular() because the widget can be used anywhere: is_singular() check that we are in a post; then get_queried_object() will return the current post object and $post->ID won't be empty. I use is_singular() because if you are in archive view there is no need to check for a exclude post ID to exclude. If you use the code in ajax call it won't work; you need to pass the post ID in the ajax request data.
    – cybmeta
    Aug 31, 2014 at 15:11
  • 1
    Although your method can work, I think it is better to localize the javascript variables as done in the example if you want to manage script dependencies correctly and limit the "pollution" of the global namespace. Just an opinion, I'm not a javascript expert.
    – cybmeta
    Sep 1, 2014 at 8:16
0

Try adding the offset parameter into the arguments..

$query = new WP_Query( array( 'offset' => 1, 's' => 'searchTerm') );
    if ($query->have_posts()){
        while ($query->have_posts()){
            $query->the_post();
            //echo the post
        }
        wp_reset_postdata();
    }
    else {
        echo 'No results';
        die();
    }
2
  • Nice try :)) The problem is that the order of the posts may differ . In my case the current page that I'm viewing is echoed at the end . <div class="post-1"></div><div class="post-current"></div> Aug 31, 2014 at 11:14
  • 1
    be aware that using 'offset' will cause problems with pagination.
    – Michael
    Aug 31, 2014 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.