Sidebar menu with a child pages regardless of depth – WP Engineer

This article was taken from WP Engineer:

In this article I want to show an example in which are the main pages in a horizontal navigation. The related sub-pages are displayed in the sidebar when you click on the main page.

For better understanding we take the following page structure:

  • Home
  • Software
    • Image Editor
      • Adobe Photoshop
      • Gimp
    • Content Managment Systems
      • WordPress
      • Drupal
      • Joomla
  • Hardware
  • About us

The pages Home, Software, Hardware and About us are in the horizontal navigation. When the user clicks on Software, for example, all the subpages of Software should be shown in the sidebar.

WordPress provides for such a task the template tag wp_list_pages() with several parameters. Since we don’t want to display all pages, only the parameter child_of is interesting for our purpose. The parameter child_of followed by an ID lists all subpages of the current page, if there exist subpages.

<?php wp_list_pages('child_of='.get_the_ID().'&title_li=<h5>'.__('Pages').'</h5>'); ?>

Now we come to the real problem. If you click on Content Management Systems in the sidebar, only the pages WordPress, Drupal and Joomla will be displayed. The Parent Pages are gone. Logically, since it displays only the children of the current page, which is Content Management Systems. But we always like to have to top page displayed too. Fortunately there is a function get_post_ancestors, which returns all parent pages in an array. Try the following:

$my_page = get_the_ID();
$anchestors = get_post_ancestors($my_page);

// click on Software
array(0) { }

// click on Content Management Systems
array(1) { [0]=>  string(2) "63" }
// 63 is the ID of Software

// click on WordPress
array(2) { [0]=>  string(2) "65" [1]=>  string(2) "63" }
// 65 iis the ID of WordPress

This would go on forever, even in more deeply nested hierarchy. Important for us are 2 things: the top page is always at the end of the array and it can return an empty array. So we just go to the end of the array and for the case that there is no parent page, we display all the subpages of this page. We write a function in our functions.php because it is easier to maintain, and may also be used in several sidebars:

function wpe_highest_ancestor(){
    global $post;

    $ancestors = array($post->ancestors);
    $page_ancestors = end( $ancestors );
    if ( !empty($page_ancestors) ) {
        $child_of = $page_ancestors;
    } else {
        $child_of = $post->ID;

    return $child_of;

Now we use this function in our sidebar:

  <?php wp_list_pages('child_of=' . wpe_highest_ancestor()); ?>

If you want to have the name of the top-level page in the sidebar, you can use the following code:

  $child_of = wpe_highest_ancestor();

As you can see, it is relatively easy to achieve appropriate solutions with WordPress.


There are no revisions for this post.

Tags: , , , , ,

No comments yet.

Leave a Reply