Exclude parent posts and display only child posts in archive

I have done this query and is working.I have a lot of child posts and i plan to display only child posts when listing the archive page of my custom post type city-guide.

$args = array(
'orderby' => 'date',
'order'   => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged
);

$query = new WP_Query( $args );

?>
    <?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>
{

.....
}

I have tried

Read More
 $all = get_posts(array('post_type'=> 'city-guide', 'posts_per_page' => -1));
 $parents = array();
 foreach ($all as $single)
 {
    $kids = get_children($single->ID);  
    if(isset($kids) && !empty($kids) && count($kids) >= 1)
    {
        $parents[] = $single->ID;
    }
  }

$args = array(
'orderby' => 'date',
'order'   => 'DESC',
'post_type' => 'city-guide',
'post__not_in' => $parents,
'posts_per_page' => 36,
'paged' => $paged
);

$query = new WP_Query( $args );

 ?>
    <?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>

{
....
}

This did not work.Please help me find out where i went wrong.

Related posts

4 comments

  1. I know it’s an old question but hoping I can help someone that finds their way here looking for the same thing I was.

    You can show ONLY child posts by excluding any posts with post_parent = 0 using the ‘post_parent__not_in’ argument:

    $args = array(
        'orderby' => 'date',
        'order'   => 'DESC',
        'post_type' => 'city-guide',
        'posts_per_page' => 36,
        'paged' => $paged,
        'post_parent__not_in' => array(0)
    );
    

    This avoids the need to loop thru each parent post to get each child.

  2. I see you are trying to push the IDs into an array but why not just use the IDs while you are looping through them while getting the children within the loop at the same time? The example below is how I would tackle this.

    <?php
    $args = array(
        'orderby' => 'date',
        'order'   => 'DESC',
        'post_type' => 'city-guide',
        'posts_per_page' => 36,
        'paged' => $paged
        );
    
    $query = new WP_Query( $args );
    
    $i=1; while( $query->have_posts() ): $query->the_post();
    
    $parentID = get_the_ID();
    
    $childrenArgs = array(
                'post_type' => 'page',
                'post_parent' => $parentID ,
                );
    
            $children = get_children($childrenArgs);
    
            foreach ($children as $child){
    
                echo '<h1>' . $child -> post_title . '</h1>';
    
                $content = $child -> post_content;
                $content = apply_filters('the_content', $content);
                $content = str_replace(']]>', ']]&gt;', $content);
                echo $content;
            }
    
    endwhile;
    
    ?>
    
  3. I think you need to look into the action pre_get_posts. Something like this in your functions.php would do the trick.

    function namespace_custom_query_vars( $query ) {
      if ( !is_admin() && $query->is_main_query()) {
        if ( $query->query["post_type"] == 'custom_post_type' ) {
          $query->set( 'post_parent__not_in', 0 );
        }
      }
      return $query;
    }
    add_action( 'pre_get_posts', 'namespace_custom_query_vars' );
    

    There’s a decent post about this here. Though note that the code on this page does not compile for small syntax errors.

  4. What about using relations? A simple disjunctive union should do the charm.

    $args = array(
        'post_type'      => POST_TYPE,
        'posts_per_page' => 36,
        'orderby'        => 'date',
        'order'          => 'DESC',
        'tax_query'      => array(
                                'relation' => 'AND',
                                array(
                                    'taxonomy' => POST_TAXONOMY,
                                    'field'    => 'slug',
                                    'terms'    => $tax_slug,
                                    'include_children' => true
                                ),
                                array(
                                    'taxonomy' => POST_TAXONOMY,
                                    'field'    => 'slug',
                                    'terms'    => $tax_slug,
                                    'include_children' => false,
                                    'operator' => 'NOT IN'
                                )
                            )
    );
    

    Or is there a reason why not to consider this?

Comments are closed.