Google seems all purple on this subject, if you know what I mean. I've searched for this topic forever to find a solution.

I want to build a finder/explorer feel to my categories, so when browsing to a category, I only want to display the direct children of the category - not posts in sub categories of this category.

I would like to alter the current query if possible, and not do any SQL quries.

I tried:

$posts = query_posts('cat='.$cat.'&child_of='.$cat.'&parent='.$cat);

And a whole bunch of other stuff.. But I'm running out of ideas...

2 Answers 2


I assume that by "direct children of category" you mean "posts directly assigned to the category" and not "posts assigned to child categories of the category specified".

The answer is in the Codex:

Display posts that have this category (not children of that category), using category id:

$query = new WP_Query( 'category__in=4' );


Second, do not use query_posts(). It clobbers several globals and just makes a mess. Use WP_Query.

$q = new WP_Query(
    'category__in' => $cat,

That will create a secondary Loop. To alter the main query, you need to hook into pre_get_posts, as explained in the Codex, again on the query_posts() page:

query_posts() is overly simplistic and problematic way to modify main query of a page by replacing it with new instance of the query. It is inefficient (re-runs SQL queries) and will outright fail in some circumstances (especially often when dealing with posts pagination). Any modern WP code should use more reliable methods, like making use of pre_get_posts hook, for this purpose.

In other words:

function no_cat_kids_wpse_143042( $query ) {
  if ( $query->is_main_query() && $query->is_front_page() ) {
    $query->set( 'category__in', 123 );
add_action( 'pre_get_posts', 'no_cat_kids_wpse_143042' );

I don't know what conditionals you need-- this, if ( $query->is_main_query() && $query->is_front_page() )-- and I don't know how you are generating the $cat variable, but that is the idea.

Place that code in functions.php or a plugin. It has to execute before the page template loads to effect the main query.

  • When navigating to a category, I only want to show posts that are in this category, not posts from sub-categories of the specific category. Make sense? :-) May 1, 2014 at 13:56
  • Yes, that is what I thought, and that is what this code does. You are doing something wrong or your data does not look like you think it does. Did you create a loop to display the results?
    – s_ha_dum
    May 1, 2014 at 14:00
  • No, I didn't. I'm using it on the index.php, to filter the results, before have_posts(). I would like the rest of the template to work as it does now, and only "filter" the query, or replace it... Is that possible? May 1, 2014 at 14:02
  • 1
    It works great now. I just had to figure out how to use your approach. I needed to add the $q to the have_posts() like this: ´$q->have_posts()` and likewise with the_post(). Thank you for your time. May 1, 2014 at 14:39

Here is example:

add_action('pre_get_posts','search_filterr');function search_filterr($query) {
    if ( !is_admin() && $query->is_main_query() )   {
        if ( $query->is_search ) {  
                $query->set('post_type',  array('post','custom-posttt-too')   );    
                $query->set('category__in', 999 );   <------ enter the ID of your category!
  • Please add a proper explanation to your code. I use this is not an explanation Apr 15, 2015 at 4:27
  • @PieterGoosen i have modified the code, and entered the comment. Now, would you revert your negative rating? :)
    – T.Todua
    Apr 21, 2015 at 19:27
  • You can maybe extend a bit more, but it looks better. :-) Apr 21, 2015 at 19:33

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.