Trying to filter out specific posts that have certain meta_key from the main query... problem is it doesnt work with pagination which is my issue here.

Anyone knows how to solve this?

$paged = (end( explode( '/', $_SERVER['REQUEST_URI'] ) )) ? end( explode( '/', $_SERVER['REQUEST_URI'] ) ) : 1;
$posts_per_page = 10;
$offset = ($paged-1) * $posts_per_page;     
function strip_codes_deals ($where = '', $ignore_posts) {
    global $wpdb, $ignore_posts;
    if (count($ignore_posts) > 0) {
        $where .= ' AND ' . $wpdb->posts . '.ID NOT IN(' . implode (',', $ignore_posts) . ') ';
    //echo $where;
    return $where;
$wp_query = new WP_query( 'post_type=deals&orderby=date&order=desc&posts_per_page='.$posts_per_page.'&paged='.$paged.'&meta_key=codes-deal' );
//          echo '<pre>';
//          print_r($wp_query);
//          echo '</pre>';
$ignore_posts = array();
if($wp_query) {
    foreach ($wp_query->posts as $post) {
        $codes_deal = get_post_meta($post->ID, "codes-deal", true);
        if($codes_deal == 1) {
            $ignore_posts[] = $post->ID;
    echo '<pre>';
    echo '</pre>';              
add_filter( 'posts_where', 'strip_codes_deals' );
query_posts( $query_string . '&post_type=deals&orderby=date&order=desc&posts_per_page='.$posts_per_page.'&paged='.$paged );
remove_filter( 'posts_where', 'strip_codes_deals' );

This works for the first page, but all other pages are ignored. Any ideas how to fix this?

  • query_posts? =o
    – Tom J Nowell
    Commented Mar 25, 2013 at 14:38

1 Answer 1


You are doing a few different things wrong-- or at least convoluted and suspect-- in that code and I am sure that that is resulting in your query results getting out of sync with the pagination. You've got a couple of queries in there, including one made by query_posts which you should really never be using at all, plus some filters. Honestly, I didn't crawl through it to work out exactly what is wrong but I believe that, primarily what you need is a meta query.

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
    'post_type' => 'deals',
    'meta_query' => array(
            'key' => 'codes-deal',
            'compare' => 'EXISTS'
    'paged' => $paged 
$query = new WP_Query( $args );

Secondarily, you need to clean up your pagination. See the first line. I can't tell if you actually want to filter out posts that "that have certain meta_key" as you stated or if you want to filter the ones with 'codes-deals' = true but I went with what you said. You can edit in your other parameters-- orderby, etc. Be aware that 'compare' => 'EXISTS' only works in 3.5 or better.

That code is almost a copy/paste from the Codex. All I did was edit in some of your values. The Codex is your friend. Love it.

Now, to apply that to the main query. For that you need pre_get_posts, which is a lot more convenient than trying to manipulate the WHERE clause with the post_where filter.

function exclude_codes_deals_wpse_92268($qry) {
    if (is_main_query()) {
        $qry->set('meta_query', array(array(
             'key' => 'codes-deal',
             'compare' => 'EXISTS'
        $qry->set('post_type', 'deals');

Untested but I believe I have that right. Again, you can edit in any other parameters you need.

That will globally alter your main query, which is what you said you wanted to do, but I have my doubts. With that code in place only the 'deals' post type will show up, unless you specifically create queries to pull other content. I suspect that there are other conditions for altering the query besides just that it is the main query.

Your Answer

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

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