Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.
<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC', 'meta_key' => featured_product, 'meta_value' => 1)); ?>


<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC')); ?>

I have 2 queries, first to show meta key with featured_product eq 1. So I want to exclude all the featured products on the second query. How can i do that please? Thanks!

share|improve this question
add comment

4 Answers

up vote 6 down vote accepted

I've never had any luck getting the meta compare to work either--but I came up with a workaround for this exact situation (having "featured" items at the top of the page).

First, you probably shouldn't be using query_posts for both queries. You should use a custom query for at least the first one. Then, while you're running that loop, keep the ids of any "featured" posts in a variable. When you run your second loop, you can use the "post__not_in" arg to exclude the featured ones. Like so:

// Set up a custom query
$featured_query = new WP_query();

// Your query args
    $featured_args=array(
        'post_type'=>'post',
        'meta_key'=>'featured_product',
        'meta_value'=>'1'
    );

// Run it
    $featured_query->query($featured_args);

    if ($featured_query->have_posts()) {

    while ($featured_query->have_posts()) {

            $featured_query->the_post();

        // Remember the featued ID
        $featured_post_id = get_the_ID(); 

        // Render your featured post here

    }

}

// Set up the args for your main query
$args = array(
        'post_type' => 'post',
        'post__not_in' => array($featured_post_id) // Don't show the featured post
    );

// Now run your main query and so on...
share|improve this answer
    
post__not_in is probably the only way to do this, if you want to include posts that have featured_product not set to 1, or not set at all (which is maybe why eileen's answer fails). Rarst also gave a good overview of query_posts() vs get_posts() –  Jan Fabry Nov 12 '10 at 18:33
    
Good workaround. Another possibility is using a category or tag for your featured category, rather than a custom field. Then you can use "cat__not_in" or "tag__not_in" in your query to exclude the featured posts. –  goldenapples Nov 12 '10 at 18:45
    
it has to be as a page item, so can't use cat or tag, thanks. –  ray Nov 12 '10 at 19:11
    
@ray: Have you tried calling register_taxonomy_for_object_type('category', 'page')? This should allow you to use categories for pages too. Use post_tag instead of category for tags. –  Jan Fabry Nov 12 '10 at 19:27
add comment

MathSmath's answer is ok, but it's very inefficient and would not scale to a WordPress site with 100,000+ posts or what have you. Doing a WP_Query() for 1000 posts is going to be slow enough.

Rather than using a posts_not_it (which would pass a query long string if you hade several thousand posts here) if you have MySQL 4.1+ it would be better to use a subquery to exclude the posts you don't want.

Here is a slightly modified example I am using on a site with 250,000+ posts.

// add a filter to 'posts_where' to add the subquery
add_filter( 'posts_where', '_exclude_meta_key_in_posts_where' );    

// make the query, the below function will be called
query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC'));

function _exclude_meta_key_in_posts_where( $where ) {

    global $wpdb;
    return $where . " AND $wpdb->posts.ID NOT IN ( SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = 'featured_product' AND meta_value > '' )";
}

//remove the filter incase we do any more query_posts()s
remove_filter( 'posts_where', '_exclude_meta_key_in_posts_where' );

You could probably do it all in one create_function() though I am not sure if that is very efficient, but would be less lines:

// add a filter to 'posts_where' to add the subquery
add_filter( 'posts_where', create_function( '$where', 'global $wpdb; return $where . " AND $wpdb->posts.ID NOT IN ( SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = \'featured_product\' AND meta_value > \'\' )";' ) );

I didn't test the create_function() example.

share|improve this answer
    
This worked beautifully for me - Thank you! –  Jonathan Wold Nov 1 '11 at 1:12
add comment

I haven't tried this, but some research let me to this. Using meta_compare you can check if meta_value does not equal 1 display the posts.

<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC', 'meta_value' => featured_product, 'meta_compare' => '!=', 'meta_value' => 1 )); ?>
share|improve this answer
    
Thanks for that, but it doesn't work to me. it won't show any posts on the second query –  ray Nov 12 '10 at 17:24
    
Did you reset the query after the first one? What about trying less than instead of !=? –  eileencodes Nov 12 '10 at 17:34
    
what do you mean 'less than' please? and wp_reset_query(); to reset right, yeah it was there. –  ray Nov 12 '10 at 17:39
    
yeah, i see what you mean <= or < I tried but no luck –  ray Nov 12 '10 at 17:44
    
Make sure that 'featured_product' is a string in quotes in the array. featured_product should be`'featured_product'` –  kevtrout Nov 12 '10 at 17:45
show 4 more comments

My solution was to add the custom field with a 'false' value to all of the existing posts and to hook the creation of new posts in order to add the field to them as well.

I'm not sure if this is a more efficient way to handle this situation but I wanted to stay away from custom SQL queries.

The following is a one-time-use function I used for adding the field to all existing posts:

function unfeature_all() {
    $args = array(
        'numberposts'   => -1,
    );

    $posts = get_posts( $args );

    foreach ($posts as $post) {
        $status = get_post_meta($post->ID, 'featured_post', true);
        if (!$status) {
            update_post_meta($post->ID, 'featured_post', false);
        }
    }

}

if (current_user_can('manage_options')) unfeature_all();
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.