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

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 ){
        //....
    });
});
  • 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. – TGeorge Aug 31 '14 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 ? – TGeorge Aug 31 '14 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 '14 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 '14 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 '14 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();
    }
  • 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> – TGeorge Aug 31 '14 at 11:14
  • 1
    be aware that using 'offset' will cause problems with pagination. – Michael Aug 31 '14 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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