0

I'm using wp_list_pages() to display a menu of child pages.

The structure is nice and simple. Looks like this: http://cl.ly/image/0w1Q1q2D3D18

The menu works perfectly when on a child page: http://cl.ly/image/3O310E0s2B3d

But, alas, does not work when on the parent page: http://cl.ly/image/3w0T3Q2s4347

Seems so simple, but i just can't get to the bottom of it.

Here's my wp_list_pages() code:

<?php

            $topmost_parent = $post->post_parent;

            $args = array(
                'post_type'    => 'guides', 
                'sort_column' => 'menu_order',
                'title_li'     => __(''),
                'echo' => 0, 
                'exclude' => $topmost_parent
                );

            $children = wp_list_pages( $args );

            if ($children) :
        ?>

            <nav id="menu-context">
                <ul class="menu">
                    <?php echo $children; ?>
                </ul>
            </nav>

        <?php endif;?>

Using that $topmost_parent trick works until I'm on the parent page. Anyone got a new trick? =)

1
  • Btw: ` <?php var_dump($topmost_parent); ?>` returns '14' when on a child page, but returns '0' when on the parent page. Like so: cl.ly/image/1p270B032t3A
    – saltcod
    Commented Aug 22, 2012 at 17:39

3 Answers 3

1

Your code won't work if you have more than one parent page or multiple levels of child pages. Use get_ancestors to get the top parent page, and use the child_of argument of wp_list_pages rather than exclude to only output pages from that branch.

1
  • Of course. Exactly. Thanks a million. Ancestors ftw.
    – saltcod
    Commented Aug 22, 2012 at 17:56
0

A more detailed explanation for those to follow.

You first need to sort out if the page you're looking at has ancestors. If it is a child page, it has an ancestors, if it's a parent page, it does not have an ancestor. This will determine that for you:

if (!$post->post_parent):
                    // will get the subpages of this top level page
                    $parent = $post->ID;
                elseif ($post->ancestors):
                    // now can get the the top ID of this page
                    // WordPress puts the IDs DESC, which is why the top level ID is the last one
                    $parent = end($post->ancestors);
                endif;

After that, you just need to use the $parent variable you just setup as the value in the child_of argument. Thusly:

$args_for_step_by_steps = array(
                'post_type'    => 'guides', 
                'sort_column' => 'menu_order',
                'title_li'     => __(''),
                'echo' => 0, 
                'child_of' => $parent
                ); 

And so the whole function then to get child pages only:

    <?php
        if (!$post->post_parent):
            // will get the subpages of this top level page
            $parent = $post->ID;
        elseif ($post->ancestors):
            // now can get the the top ID of this page
            // WordPress puts the IDs DESC, which is why the top level ID is the last one
            $parent = end($post->ancestors);
        endif;


        $args = array(
            'post_type'    => 'guides', 
            'sort_column' => 'menu_order',
            'title_li'     => __(''),
            'echo' => 0, 
            'child_of' => $parent
            );

        $children = wp_list_pages( $args );

        if ($children) :
    ?>



        <nav id="menu-context">
            <ul class="menu">
                <?php echo $children; ?>
            </ul>
        </nav>

    <?php endif;?>
0

Or ... create a primary menu like so:

if ( function_exists( 'register_nav_menus' ) ) {
    register_nav_menus( array( 'primary' => 'Primary Navigation' ) );
}

Then in the admin, go to Appearance > Menus and select the primary menu from the drop down menu. You just don't include the pages you don't want.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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