How to display sub child pages only when on direct parent page?

I have a pretty normal page hierarcy structure like this:

- Main page
- - Child page
- - Child page 2
- - Child page 3
- - - Sub child page
- - - Sub child page 2
- - Child page
- - Child page
- - - Sub child page
- Main page 2
- - Child page
...

When I am on any page I want to display a menu on the sidebar with all the child pages, but not the main page.
This, I can do with this set of arguments which I got from another answer:

Read More
<?php 
$child_of_value = ( $post->post_parent ? $post->post_parent : $post->ID );
$depth_value = ( $post->post_parent ? 2 : 1 );
$args = array( 
        'depth' => $depth_value,
        'sort_column' => 'menu_order', 
        'sort_order' => 'asc',
        'title_li' => '',
        'child_of' => $child_of_value,
        'echo' => 0
);

      $children = wp_list_pages($args);
?>

This way, in the menu are shown all the child pages belonging to same main page. The problem is with sub child pages. I want to show them only when I’m in their direct parent page, but together with all the other pages.

So for example, if I’m in a child page without any other child it would appear like this:

- - Child page <---
- - Child page 2
- - Child page 3
- - Child page
- - Child page

while if I’m on the third, it would appear like this:

- - Child page
- - Child page 2
- - Child page 3 <---
- - - Sub child page
- - - Sub child page 2
- - Child page
- - Child page

The same would it be, then, if I’m in a sub child page, where I would show the same.
Is there any way I can achieve this modifying the arguments?

Related posts

Leave a Reply

1 comment

  1. Not by just modifying the arguments, but it can be achieved through CSS. If you manipulate the depth like you’re doing, it will get that depth for all links in the menu. This is fine for depth zero, but when you get to depth 1 & beyond, it will show child menus for all of those pages that have children.

    Instead, here is the code to generate the menu listing all subpages of your top level page (including grandchildren, great-grandchildren, etc) with all depths, which can then be hidden or shown based on the current page:

    <?php
        global $post;
        $parent_id = wp_get_post_parent_id( $post->ID );
        $top_parent = $post->ID;
        while( $parent_id ){
            if( $parent_id > 0 ){
                $top_parent = $parent_id;
            }
            $parent_id = wp_get_post_parent_id( $parent_id );
        }
        $args = array( 
            'sort_column' => 'menu_order', 
            'sort_order' => 'asc',
            'title_li' => '',
            'child_of' => $top_parent,
            'echo' => 1
        );
        $children = wp_list_pages($args);
    ?>
    

    In your stylesheet, you can use these:

    .page_item_has_children > .children {display: none;} /*hides the submenu*/
    .page_item_has_children.current_page_item > .children,
    .page_item_has_children.current_page_ancestor > .children {display: block;} /*shows the submenu for the current page or when on its subpages /*