wordpress exclude posts from loop if only has one specific category

I have this category which is “community-posts” I don’t want it to appear on my homepage loop so I added this to my query

<?php query_posts(array('showposts' => 4,'category__not_in' => $id_communityposts,));?>

This is working fine with me but some “community-posts” I want them to be featured on the homepage loop. (exception)

Read More

so I want to only exclude the posts that has one category as “community-posts” if it has this category and more its shows normally.

Related posts

2 comments

  1. First thing do not use query_posts – it should never be used as it alter the main query. Use get_posts instead – it’s much safer and perform the same task.

    To answer your question, let’s first imagine how the query would look in SQL (assuming your $id_communityposts is equal to 2) :

    SELECT DISTINCT wp_posts.* 
    FROM wp_posts, wp_postmeta
        LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
        LEFT JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
    WHERE 
        wp_posts.ID = wp_postmeta.post_id AND
        (
            (wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id NOT IN(2))
            OR
            (wp_postmeta.meta_key = 'featured' AND wp_postmeta.meta_value = 1)
        )
    ORDER BY wp_posts.post_date DESC
    LIMIT 4
    

    So we query the post, post meta and taxonomy tables and make two possible conditions:

    • The category ID is not 2, OR
    • The featured meta key of the post is set to 1 (change this to whatever key / value depending of how you store the “featured” information).

    For that kind of specific cases, get_posts isn’t really good to play with – querying the DB with WPDB will give you much more flexibility.

    $posts = $wpdb->get_results(
        "SELECT DISTINCT $wpdb->posts.* 
        FROM $wpdb->posts, $wpdb->postmeta
            LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
            LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
        WHERE 
            $wpdb->posts.ID = $wpdb->postmeta.post_id AND
            (
                ($wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id NOT IN(2))
                OR
                ($wpdb->postmeta.meta_key = 'featured' AND $wpdb->postmeta.meta_value = 1)
            )
        ORDER BY $wpdb->posts.post_date DESC
        LIMIT 4"
    );
    

    Let me know if you run into any issue as it is an untested query.

  2. If I understood the question correctly , The simplest solution, not involving complicated SQL would be something along the lines of :

         // NOT TESTED ! 
    if ( count(get_the_category()) > 1 ) { // this means there are more than single category
        // show the desired posts 
        } else {
        // dont show 
        }
    

    read get_the_category() in codex

    Along the same logic lines you could also use wp_get_post_categories

Comments are closed.