1

I have such a wp query args:

$args = array(
  'post_type'=> 'myposttype',
  'posts_per_page' => 10,
  'meta_query' => array(
  'relation' => 'AND',
   array('key' => 'routeFrom','value' => 'rome','compare' => 'LIKE'),
   array('key' => 'routeTo','value' => 'paris','compare' => 'LIKE'),
   )    
);

Each my post has custom field routeFrom and routeTo. In this example if routeFrom equal to Rome and routeTo equal to Paris wp query displaying those posts.

The problem is that sticky posts appear no matter what meta query i'm using.

I want to display particular sticky posts if they only match meta query.

Real life example would be: I have a route search page where i would like to display sticky post on top of all posts, but only if it ALSO meets meta query (in this case particular route).

I'm using sticky posts plugin "Sticky Custom Post Types", but posts are stored in the global ‘sticky_posts’ option field, just like regular posts.

Any help?

Updated code:

$stickyargs = array(
  'post_type'=> 'trips',
  'posts_per_page' => -1,
  'post__in' => get_option( 'sticky_posts' ),
  'meta_query' => array(
  'relation' => 'AND',
   array('key' => 'routeFrom','value' => $_GET['from'],'compare' => 'LIKE'),
   array('key' => 'routeTo','value' => $_GET['to'],'compare' => 'LIKE'),
   )    
);

$args = array(
  'post_type'=> 'trips',
  'paged'    => $paged,
  'posts_per_page' => 10,
  'post__not_in' => get_option( 'sticky_posts' ),
  'meta_query' => array(
  'relation' => 'AND',
   array('key' => 'routeFrom','value' => $_GET['from'],'compare' => 'LIKE'),
   array('key' => 'routeTo','value' => $_GET['to'],'compare' => 'LIKE'),
   )    
);

$search = new WP_Query($args);
$searchsticky = new WP_Query($stickyargs);
?>

<?php if ( $searchsticky->have_posts() ) : ?>
    <?php while ( $searchsticky->have_posts() ) : $searchsticky->the_post(); ?>
        <div class="search_item">
            <?php the_content(); ?>>
        </div>
    <?php endwhile; ?>
    <?php else : ?>
        Not found
<?php endif; wp_reset_query(); ?>

<?php if ( $search->have_posts() ) : ?>
    <?php while ( $search->have_posts() ) : $search->the_post(); ?>
        <div class="search_item">
            <?php the_content(); ?>>
        </div>
    <?php endwhile; ?>
    <?php else : ?>
        Not found
<?php endif; wp_reset_query(); ?>

2 Answers 2

1

Custom queries and sticky posts are quite a curve ball to work with. I don't know how your setup looks and what exactly is your user case, but your best solution here would be to run two queries here, the first one to get your sticky posts and the other one to display normal posts

Your first query's arguments will look something like

$args = array(
  'post_type' => 'myposttype',
  'posts_per_page' => -1,
  'post__in' => get_option( 'sticky_posts' ),
  'ignore_sticky_posts' => 1,
  'meta_query' => array(
  'relation' => 'AND',
   array('key' => 'routeFrom','value' => 'rome','compare' => 'LIKE'),
   array('key' => 'routeTo','value' => 'paris','compare' => 'LIKE'),
   )    
);

Your second query arguments you will need to exclude these stickies

$args = array(
  'post_type'=> 'myposttype',
  'posts_per_page' => 10,
  'post__not_in' => get_option( 'sticky_posts' ),
  'meta_query' => array(
  'relation' => 'AND',
   array('key' => 'routeFrom','value' => 'rome','compare' => 'LIKE'),
   array('key' => 'routeTo','value' => 'paris','compare' => 'LIKE'),
   )    
);

Just make sure that you reset both queries.

As I said before, I do not know your exact setup and user case, but if this is suppose to be the main query, you should look at pre_get_posts to alter the main query accordingly. If so, look at this post I have recently done to include sticky posts outside the home page.

EDIT

I totally forgot to add ignore_sticky_posts to the first set of query arguments. It should work now. I have updated the code accordingly

Just one or two notes on your code

  • You should use wp_reset_postdata() to reset your queries, not wp_reset_query(). The latter is used with query_posts which you should never use. Also, wp_reset_postdata() should be used between endwhile and endif

  • To exclude the sticky post query from paged pages, simply warp the code in a if ( !is_paged() ) { YOUR STICKY POST CODE } condition

9
  • Thanks Peter. It looks like possible solution here. But i think where will be a problem with pagination. As sticky posts will appear in every next page. It would be nicer to have it only once on top position. Anyway it's a good start to experiment with. i will try this solution.
    – MIC
    Apr 28, 2015 at 6:24
  • Just wrap the first query in an if ( !is_paged() ) {} condition Apr 28, 2015 at 6:28
  • Peter good idea :) thanks. i will try it a bit later :)
    – MIC
    Apr 28, 2015 at 6:49
  • Peter the problem is that stickypost still appears even if meta query doesn't match. Could you please check my updated code at first comment.
    – MIC
    Apr 28, 2015 at 7:41
  • 1
    Please see my edit Apr 28, 2015 at 12:56
2

You can ignore sticky posts by adding

'ignore_sticky_posts' => true,

to your query. You can also set ignore_sticky_posts to 1.

Please note that a post is still delivered if it is sticky, but matches the other criterias.

1
  • the problem is that sticky post is now not sticky post anymore. I'm still want that it would be sticky post BUT only if matches other criterias. Real life example would be: I have a route search page where i would like to display sticky post on top of all posts, but only if it ALSO meets meta query (in this case particular route).
    – MIC
    Apr 27, 2015 at 10:51

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.