tags:

views:

52

answers:

2

I have a function below whose purpose is to create a listing of posts where the category assigned to each post is "top-menu". However, I first want to exclude any posts where the category is "hidden"...

How can I edit this code to do that?

global $post;
$cat = get_cat_ID('top-menu');
if ($cat > 1) 
  $myposts = get_posts('numberposts=5&category='.$cat);
else
  $myposts = get_posts('numberposts=10');
foreach ($myposts as $post) :
?> 
<li>
  <a href="<?php the_permalink(); ?>">
    <?php the_title(); ?>
  </a>
</li>
<?php endforeach; ?>
+2  A: 

This should do what you want. Not sure why you had the if statement, so feel free to incorporate again if you need it. You can always just use category and give it an id instead of category_name as I am using here as a shortcut.

$exclude_cat = get_cat_ID('hidden');
$include_cat = get_cat_ID('top-menu');

$myposts = get_posts( array(
    'numberposts'      => 5,
    'category__in'     => array( $include_cat ),
    'category__not_in' => array( $exclude_cat )
));

EDIT: category_name cannot be combined with category__not_in, so I changed the code slightly so both filters would be run.

I have tested this and it works in WordPress 2.8, just be sure to supply the actual category name in the get_cat_ID calls and not the slug by accident.

Doug Neiner
Don't believe you can combine category parameters like that. Could use 'category__in' with an array of category ids that does NOT contain the hidden category.
Michael
You were half right :) You cannot combine `category_name` and `category__not_in` but you can combine `category__in` and `category__not_in` with great success. Thanks for pointing the problem out. I have fixed my code example and tested that it works.
Doug Neiner
Oops, have to correct that statement. category__not_in doesn't work with category_name, but category__not_in works with the 'cat' => 4 argument (where 4 is the category id)
Michael
Okay you got there first dcneiner. Good point.
Michael
Nice to know you can use plain 'ol `cat` as well. Thanks for testing!
Doug Neiner
Thanks dc. This works perfectly.
Scott B
+1  A: 

Noting that dcneiner's revised suggestion works. That query generates this SQL

SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  
INNER JOIN wp_term_relationships 
  ON (wp_posts.ID = wp_term_relationships.object_id) 
INNER JOIN wp_term_taxonomy 
  ON (wp_term_relationships.term_taxonomy_id = 
    wp_term_taxonomy.term_taxonomy_id)  
WHERE 1=1  
  AND wp_term_taxonomy.taxonomy = 'category'  
  AND wp_term_taxonomy.term_id IN ('3')  
  AND wp_posts.ID NOT IN 
  ( SELECT tr.object_id FROM wp_term_relationships AS tr 
    INNER JOIN wp_term_taxonomy AS tt 
      ON tr.term_taxonomy_id = tt.term_taxonomy_id 
    WHERE tt.taxonomy = 'category' 
    AND tt.term_id IN ('1') ) 
    AND wp_posts.post_type = 'post' 
AND (wp_posts.post_status = 'publish' 
  OR wp_posts.post_status = 'private') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC LIMIT 0, 5
Michael