Show just one level of child pages, wp_list_pages woe

I’m working on a site that has a fairly large page structure a few levels deep – in some sections there are a lot of pages.

The basic setup is something like this…

Parent
Parent
Parent
-Child
-Child
--Grandchild
--Grandchild
--Grandchild
---GreatGrandchild
-Child
-Child
--Grandchild
--Grandchild
--Grandchild
---GreatGrandchild
-Child
Parent
-Child
Parent
Parent
-Child
-Child
--Grandchild
---GreatGrandchild
--Grandchild

You get the picture – just imagine a lot more pages!

My normal solution of submenus works fine normally (taken straight from the Codex), because I’m working on much smaller sites. This site results in a massively long menu that is far to big to be useful.

What I would like to do is just to show the level directly below the page that is currently being viewed. Basically an ‘In this section…’ menu.

No matter what combination of wp_list_pages snippet I’ve found I’ve only been able to get all or nothing.

Also because there are some sections that don’t have children it needs to just show the top level links when no children are present.

Hopefully that makes sense – I’ve been tearing my hair out all day over this! Any help greatly appreciated!

EDIT

Right, I’ll ad it here. Sorry for being a noob!

So huge thanks to @chip-bennet for getting me this far!

I now have this code that does nearly everything I need it to.


$output = wp_list_pages('echo=0&depth=1&title_li=Sections' );

        if (is_page( )) {

          $page = $post->ID;

          if ($post->post_parent) {
            $page = $post->post_parent;
          }

          $children=wp_list_pages( 'echo=0&child_of=" . $page . "&title_li=' );


          if ($children) {
            $output = wp_list_pages( array(
                // Only pages that are children of the current page
                'child_of' => $post->ID,
                // Only show one level of hierarchy
                'depth' => 1,
                'title_li' => 'In this Section'
            ) );
          }


        } 

        echo $output;

This works exactly as I want until I hit the bottom of the tree, when it outputs nothing.

Chip has given me the code again to show the peers of the page rather than looking for more children – however my lack of proper PHP skills is meaning I’m having trouble adding it to this code.

4 s
4

This should work, using nothing more than the available argument-array parameters for wp_list_pages(): specifically, depth and child_of.

To display one level of hierarchy, for descendant pages of the current page:

<?php
// Globalize the $post variable;
// probably already available in this context, but just in case...
global $post;
wp_list_pages( array(
    // Only pages that are children of the current page
    'child_of' => $post->ID,
    // Only show one level of hierarchy
    'depth' => 1
) );
?>

There should be no need to resort to a custom walker class.

EDIT

TO show the top-level links as well, simply change a couple of the parameters:

<?php
// Globalize the $post variable;
// probably already available in this context, but just in case...
global $post;
wp_list_pages( array(
    // Only pages that are children of the current page's parent
    'child_of' => $post->post_parent,
    // Only show two level of hierarchy
    'depth' => 2
) );
?>

Note the change of 'child_of' => $post->ID to 'child_of' => $post->post_parent, which will include pages of the current page’s parent page, and the change of 'depth' => 1 to 'depth' => 2, which will include the current page’s siblings, and their children.

EDIT 2

Okay, here’s how I would handle the code you just added. First, I would use a proper array, rather than an array string. Then, I would query for context/child-pages before building the wp_list_pages() argument array, then, just call wp_list_pages() once:

// Use parent page if exists, else use current page    
$child_of_value = ( $post->post_parent ? $post->post_parent : $post->ID );
// Depth of 2 if parent page, else depth of 1
$depth_value = ( $post->post_parent ? 2 : 1 );
// Build argument array
$wp_list_pages_args = array( 
    'child_of' => $child_of_value,
    'depth' => $depth_value,
    'title_li' => 'Sections'
);
// Now, output the result
wp_list_pages( $wp_list_pages_args );

We’ll need more complex code, if you actually need to output separate lists.

Leave a Comment