How can I hide children of draft pages using wp_list_pages()?

Great answers above. I took on the challenge trying to find yet another way to solve this.

The exclude parameter:

We could try:

'exclude' => wpse_exclude_drafts_branches()

where:

function wpse_exclude_drafts_branches()
{
    global $wpdb;
    $exclude = array();
    $results = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} where post_status="draft" AND post_type="page" " );
    $exclude = array_merge( $exclude, $results) ;
    while ( $results ):
        $results = $wpdb->get_col( "SELECT DISTINCT ID FROM {$wpdb->posts} WHERE post_type="page" AND post_status="publish" AND post_parent > 0 AND post_parent IN (" .  join( ',', $results ) . ") " );
        $exclude = array_merge( $exclude, $results) ;
    endwhile;
    return join( ',', $exclude );
}

and the number of queries depends on the tree depth.

Update:

The exclude_tree parameter:

I just noticed the exclude_tree parameter mentioned on the Codex page, so I wonder if this would work (untested) to exclude the whole of the draft nodes branches:

$exclude = get_posts(
    array( 
        'post_type'      => 'page',
        'fields'         => 'ids',
        'post_status'    => 'draft',
        'posts_per_page' => -1,
   )
);

and then use:

'exclude_tree' => join( ',', $exclude ),

with wp_list_pages().

Leave a Comment