Custom Code: List Hierarchy for Custom Post Types

Here’s another solution to something that’s not very well documented online. In migrating a website over to WordPress, we ran into a question of how to display a hierarchical set of information, especially when recreating the many, many menus available. After creating a custom post type, loading some content and setting up some child pages, in order to avoid having to create multiple menus in WordPress for posts and their respective child pages, we decided to set it to automagically pull in a list of the child pages, regardless if we’re on a parent page or one of it’s children.

From the code below, you will need to add any necessary html/php to the titles that are printed out; the following code simply lists the titles of the child posts under a parent post.

function eyesore_list_child_pages() { 
    ob_start(); 
    global $post;
    //check if this is a parent or child post
    $args = array(
        'post_parent' => $post->ID,
        'post_type' => 'your_post_type_here' 
    );
    $children = get_children($args); 

    //if this is a parent post
    if(!empty($children)) {
        //has children
        $postsarr = array(
            'post_parent' => $post->ID,
            'post_type' => 'your_post_type_here'
            ); 
        $childQuery = new WP_Query($postsarr);
        if ( $childQuery->have_posts()) : while ( $childQuery->have_posts()) : $childQuery->the_post();
        the_title(); 
        endwhile; endif; 
        
    } else {
        //if this is a child post
        $parent = wp_get_post_parent_id($post->ID); 
        $siblingsarr = array(
            'post_parent' => $parent,
            'post_type' => 'your_post_type_here'
            ); 
        $siblings = new WP_Query($siblingsarr); 
        if ( $siblings->have_posts()) : while ( $siblings->have_posts()) : $siblings->the_post();
        the_title();
        endwhile; endif; 
    }
   return ob_get_clean();
}
add_shortcode('eyesore_childpages', 'eyesore_list_child_pages');