[resolved] How can I filter posts belonging to 2 categories with query_posts()? (20 posts)

  1. taote
    Posted 8 years ago #

    How can I get the posts that belong to 2 or more categories, (but not only one of them) with query_posts?

    If I use query_posts('cat=2,6'); it gives back all the posts that belongs at least to one of them, I need those belonging to both.

  2. Try:

  3. taote
    Posted 8 years ago #

    Otto42, I tried query_posts(array('category__and'=>'2,6')); and the query failed, but afterwards tried query_posts(array('category__and'=>array(2,6))); and it worked.

    Thank you very much, this should be documented.

  4. davidmihm
    Posted 8 years ago #

    Otto42 & taote, thanks SO much.


    works perfectly. Any ideas on how to combine that with the other query_posts parameters, i.e. &showposts= and &order= ? I can't figure out the syntax.


  5. MichaelH
    Posted 8 years ago #


  6. davidmihm
    Posted 8 years ago #

    That's terrific MichaelH, thanks so much!

  7. TBoswell
    Posted 8 years ago #

    On the same topic, only a little different...

    How can I filter subcategory posts from a category that has subcategories?

    For example, say I have a category that is hunting with the subcategories Big Game, Small Game, Waterfoul and Hunting Reports.

    Using the query_posts() how could I exclude the posts in the "hunting reports" category from the query?

    Similarly, if the Main Category, Hunting (that covered all the topics above), had only one subcategory that was "hunting reports" how would I exclude the posts from the single subcategory in the query?

    I've tried everything using exclude, hierarchy, etc. but all of them ended up listing the posts in the subcat...maybe my syntax was off but I've just had no luck and I'm pulling my hair out. I've spent three days searching google for something on this topic before finally arriving here!! Everything seems to be about wp_list_categories, which is not what I'm trying to do. I want to exclude posts from a category's subcats.


  8. Ivovic
    Posted 8 years ago #

    its not the syntax... if you include the parent category, query_posts doesn't allow you to exclude the child of that parent.

    for this, you may need to use get_posts() instead of query_posts. If you specify a category with this function, it will not gather from children by default, so you will just have to specify all the children you want, as well.

    your alternative is to make a special category called "hidden" or something, which is outside the 'hunting' heirachy, and put all your 'hunting reports' posts into the 'hidden' category as well

    if you then exclude 'hidden' from query_posts, it will correctly exclude them, even though they're also in the 'hunting reports' child category.

  9. earthmanweb
    Posted 8 years ago #

    Thanks for the help so far in this thread, very useful.

    I am having trouble with one thing, i am trying to get two sets of the latest posts that exist in categories 11,13,15,17,19,21 and then another loop that contains posts in cats: 12,14,16,18,20,22, but I ALSO want to ensure that all of the posts pulled are members of category 7 (7 is NOT the parent of the others).

    I was trying these two queries:

    query_posts(array('cat=11,13,15,17,19,21', 'category__and'=>array(7),'showposts'=>6,'orderby'=>menu_order,'order'=>ASC));
    query_posts(array('cat=12,14,16,18,20,22', 'category__and'=>array(7),'showposts'=>6,'orderby'=>menu_order,'order'=>ASC));

    but the results end up being identical. Any help you can offer is greatly appreciated, please?

  10. Ivovic
    Posted 8 years ago #

    I know its not ideal, but you won't really do a hell of a lot more processing by just looping through them all, and only outputting posts that are in category 7 based on a simple conditional.

    look up in_category() in the codex.

    what I mean is... as you go though the loop to output your posts, just skip over any that are not in cat7.

  11. earthmanweb
    Posted 8 years ago #

    Thanks for your quick response! I considered that, but was hesitant because i want to pull ONLY the most recent one from each category which is the reason for the limit of 6. I guess I could create a conditional loop:
    ie: (i=0, i++, if(i>6){[don't output]})

    but I am wondering how much extra load that is going to create when the page is getting hit thousands of times....do the results of a query like that get cached....?

  12. Ivovic
    Posted 8 years ago #

    I don't think the extra load would make very much difference really... but if load is a concern (and it should be) you should look into a plugin that caches your site properly - all of it, not just the queries.

    check out the WP Super Cache plugin.

  13. brockangelo
    Posted 8 years ago #

    I'd like to go back to the top of this thread to clarify something. When you use this format:


    is it possible to replace one of the array values with a variable? I would like to get a list of posts that are in the current category (my variable) and another (static) category - but I have not yet found a way to do this.

  14. Jeremy Clarke
    Posted 7 years ago #

    @brockangelo: You can just set up an array ouside the query_posts() function and use it as the value for category__and, like:

    $myarray = (1,2);

    At least that should work.

  15. That should be:

    $myarray = array(1,2);

    Although brock's question could be answered like this as well:

  16. Jeremy Clarke
    Posted 7 years ago #

    For the record here's a function that will let you spawn a fresh new query and add whatever arguments you want (in url var ($x=y) or array format. You can also tell it to use or ignore the existing query variables for the current view.

    // ---------------------------------
    // Replacement for query_posts.
    // Uses a new query object and takes extra arguments
    // ----------------------------------
    // $new_args - query stuff to add to $query_string, can be array or url style string
    // 	       see wp function wp_parse_args() for details
    // $ignore_existing_args - if set to true only the $new_args will be used.
    function gv_query_posts($new_args = '', $ignore_existing_args = FALSE) {
    	global $query_string ;
    	// Set up $query_string as an array unless the ignore flag is set
    	if (!$ignore_existing_args)	$existing_args = wp_parse_args($query_string);
    	// Mix together new and existing args (new_args can be string or array)
     	$args = wp_parse_args( $new_args, $existing_args );
     	// Make sure there are no duplicates
    	extract( $args, EXTR_SKIP );
    	$posts = new wp_query($args);
    	return $posts;
    } // gv_query_posts
  17. brockangelo
    Posted 7 years ago #

    Awesome guys - thanks for those replies - that does the trick.

  18. KingManon
    Posted 7 years ago #

    This helped me a lot too. I searched google for hours until I found this post by "accident". Will throw in the word intersect here so other people might find the post! Thanks.

  19. mfshearer72
    Posted 7 years ago #

    This is what I was looking for to - almost.

    I would also like to pass a variable and have it be the title of the current post (which will be matched to a category name), i.e.

    I have a post titled "problem x" and a category titled "problem x".

    I assign the variable (novice at this part so forgive me)...

    $catname = the_title;


    do this query:


    I'd like to build this in the template page, single.php, and then repeat it 3 more times for different categories.


    Will a non-numeric value work in that array?

    I'll have to brush up on multiple loops, too, but hopefully someone understands what I'm trying to do.

  20. brockangelo
    Posted 7 years ago #

    @ mfshearer72:

    Sounds like you are getting to one of the limitations that I have run across in building a CMS when you say

    I would also like to pass a variable and have it be the title of the current post (which will be matched to a category name)

    I'm using a similar approach, but I use the following instead:

    $slug = $post->post_name;

    At least, I think that is it. I'll check on Monday. I have not taken the time to document my intranet project at work, but it has been a challenge using WordPress. A quick synopsis: Pages are where all of the Staff profiles and Department profiles are kept. Each staff page is a subpage of the "Staff" page, then each department is a subpage of the "Departments" page. Then, I have assigned them to the Staff.php template or the dept.php template. I'm starting to work on Forms now (pdfs, docs, etc) and I've got those as subpages of a Forms page, using Forms.php as the template.

    The nice part is that I can assign staff members to multiple departments by categorizing them to multiple department categories. And I'll be able to assign forms to multiple categories as well. So for example on the "Human Resources" Department page, I'll be able to show all subpages of the Forms page that are categorized "Human Resources", so HR can see their forms, but IS can have the same forms on their homepage if they want.

    All that to say, I have a long list of department pages and identical category names as a way to link items back to the their respective department.

    What a nightmare. One of these days I'm going to document all of it and put it on my personal site. It was a lot of work, but it works very well and I'm sure would help others out who are attempting to develop a CMS. Another really helpful tool is creating a custom wordpress import file in Excel to create pages in bulk. That's how I added about 800 staff pages in an afternoon.

    The multiple loops is completely possible, as that is how I'm doing much of what I'm doing. But it's a Saturday and my mind is jelly. I'll post back to this on Monday with a follow up.

Topic Closed

This topic has been closed to new replies.

About this Topic