WordPress Snippet: How To Get Children Pages?

Imagine typical situation on the website, where navigation of children (or siblings) pages is located e.g. in the sidebar. How to do it in WordPress?

Firstly, this is actually important, I talk about pages, not posts. To create custom selection of posts from database, you surely use WP_Query class.

Back to our problem. The part of website sitemap could look like this:

Services
     Design
     Web Development
     Mobile Apps
     Consulting

When you are located to “Services” page, a navigation of all children pages would be placed in the sidebar.

But if you move to the service detail, e.g. “Web Development”, side menu should contain of all siblings pages links.

It is also nice practice to mark current website with “active” (or any other preffered name) class and highlight it in the list.

Solution How To Receive Children Pages

The key is get_pages function. Unlike WP_Query, get_pages doesn’t restore WP main query. In can be used in both cases, in or outside the loop.

First of all, I want to receive parent page ID:

$parent_id = wp_get_post_parent_id($post->ID);

Globally, you have access to the $post variable, which stores the object of current post (or page) data. With the help of wp_get_post_parent_id function, I get ID of the parent page.

Next thing is, I don’t know, if current page has children or not, so I check:

$children = get_pages( array( 'child_of' => $post->ID ) );

Finally, I evaluate, if there are any children, if not, I need to run one more request to database:

if( count( $children ) == 0 ) {
    $the_pages = get_pages(array(
      'parent' => $parent,
    ));
} else {
    $the_pages = $children;
}

Now you get an array of either children or siblings pages.

Another noticeable thing is that this works on all level children, If you plan to organize pages more deeply, e.g. also as grandchildren, it works fine.

Loop Throught the Results

At last, as I mentioned before, I get an array, I can loop:

<ul class="side-nav">
     <?php foreach ( $the_pages as $page ): ?>
     <li <?php if( $page->ID === get_the_ID() ): ?> class="active" <?php endif; ?>>
          <a href="<?php echo get_page_link( $page->ID ); ?>"><?php echo $page->post_title; ?></a>
     </li> 
     <?php endforeach; ?>
 </ul>

That’s it. Sidebar navigation with siblings or children pages to the current one. With marking the current page with CSS “active” class.