Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've got a site with the following structure:

About

  • Page 1
  • Page 2
  • Page 3
    • Page 3.1
    • Page 3.2

So Page 1, Page 2,... are subpages of the About page. I would like to have a sidebar that lists the pages, but only shows the subpages when needed. So when I'm on Page 1, I need to see:

  • Page 1
  • Page 2
  • Page 3

And when I'm on Page 3 I need to see:

  • Page 1
  • Page 2
  • Page 3
    • Page 3.1
    • Page 3.2

Also, when I'm on Page 3.1 or 3.2 I'd like to see the same thing. I've got following code so far:

<?php
  if($post->post_parent)
  $children = wp_list_pages("title_li=&child_of=".$post->post_parent."&echo=0&depth=1");
  else
  $children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0&depth=1");
  if ($children) { ?>
  <ul>
  <?php echo $children; ?>
  </ul>
  <?php } ?> 

But when I'm on Page 3 now, the subpages don't get listed. I've tried adapting the code in various ways, but either the subpages don't get listed, or the parent pages or siblings don't display... Anyone has a suggestion or a solution about this one? Thanks.

share|improve this question

1 Answer 1

up vote 0 down vote accepted

Here is a function that im using for submenus, maybe there is a better way to do this but i always ends up with this solution. Add this function to your theme functions.php file:

function wpse_submenu( $id, $echo = false, $showParent = true, $depth = 0 ) {
    global $wpdb, $post, $before, $page_for_posts;

    // if is a page
    if( get_post_type() == 'post' || is_paged() ) {
        $id = get_option('page_for_posts');
    }

    $the_post_ID = $id;
    $page_id = get_page( $id );
    _get_post_ancestors( $page_id );
    $ancestors = array_filter( $page_id->ancestors );
    $parent_id = count( $ancestors ) > 0 ? $ancestors[ count( $ancestors ) - 1] : $id;

    $post->ID = $id;

    $page_query = get_page( $parent_id );
    $parent_title = $page_query->post_title;
    $page_menu = wp_list_pages(' echo=0&depth='. $depth .'&title_li=&child_of='. $parent_id );

    wp_reset_query();

    // echo or not
    if( $echo ){
        $sub_pages = explode( "\n", $page_menu );

        // add class first and last class
        $last = (count( $sub_pages ) - 2);
        $sub_pages[0] = str_replace( 'class="', 'class="first ', $sub_pages[0] );           // first
        $sub_pages[$last] = str_replace( 'class="', 'class="last ', $sub_pages[$last] );    // last

        // if the parent is the current page
        if( $the_post_ID == $parent_id ){
            $class = " current_page_item";
        } else {
            $class = "";
        }

        echo '<ul class="pagenav">';

            // if to show the parent in the menu
            if( $showParent ){
                echo '<li class="parent-page page_item'. $class .'" ><a href="'. get_permalink( $parent_id ) .'">'. $parent_title .'</a></li>';
            }

            // echo all the pages
            foreach( $sub_pages as $page ){
                echo $page ."\n";
            }

        echo '</ul>';
    } else {
        return $page_menu;
    }
}

And put this where you want the submenu to bee displayed:

<?php if( wpse_submenu( $post->ID ) ) wpse_submenu( $post->ID, true, false ); ?>

And som basic css that will hide the subpages when on the first level:

.pagenav ul {
    display: none;
}
.pagenav .current_page_parent .children,
.pagenav .current_page_ancestor .children,
.pagenav .current_page_item .children {
    display: block;
}
share|improve this answer
    
Works very nice, thanks. However, adding one more level (Page 3.2.1) seems to break it. –  wp-hooves Jul 9 '12 at 12:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.