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.

This is the code from the codex most commonly used for sidebar menus. It displays the child pages of the top level ancestor and the ancestor itself.

There is one thing about this code I would like to change - I don't want the top level ancestor displayed if it has no children! It doesn't make much sense to have a one link menu which points to itself.

How can I edit this code to achieve this? I've previously asked a similar question, but was never given the correct answer. All the answers given also listed children of the parent's child (the second level child page).

In functions.php

// Sub-pages menu
if(!function_exists('get_post_top_ancestor_id')){
/**
 * Gets the id of the topmost ancestor of the current page. Returns the current
 * page's id if there is no parent.
 * 
 * @uses object $post
 * @return int 
 */
function get_post_top_ancestor_id(){
    global $post;

    if($post->post_parent){
        $ancestors = array_reverse(get_post_ancestors($post->ID));
        return $ancestors[0];
    }

    return $post->ID;
}}

Calling it:

<ul class="subpages">
    <?php wp_list_pages( array('title_li'=>'','include'=>get_post_top_ancestor_id()) ); ?>
    <?php wp_list_pages( array('title_li'=>'','depth'=>1,'child_of'=>get_post_top_ancestor_id()) ); ?>
</ul>

This code checks if a page has children, I'm curious if this could be merged with the codes above to create the correct code:

$children = get_pages('child_of='.$post->ID);?>
if( count( $children ) != 0 ) { show list as normal }
else { show "no parent" text }
share|improve this question
add comment

2 Answers 2

up vote 1 down vote accepted

Personally, I think this is the neatest, least intensive (database querying) solution:

<?php
$parentid = $post->post_parent ? @ array_pop( get_post_ancestors( $post ) ) : $post->ID;
$children = wp_list_pages(
    array(
        'child_of' => $parentid,
        'title_li' => '',
        'echo'     => false,
    )
);

if ( $children ) : ?>

    <ul class="subpages">
        <li><a href="<?php echo get_permalink( $parentid ) ?>"><?php echo get_the_title( $parentid ) ?></a></li>
        <?php echo $children ?>
    </ul>

<?php else : ?>

    Nothing!

<?php endif ?>
share|improve this answer
1  
What about active class for the parent? –  Howdy_McGee Feb 25 at 18:15
    
I found this to be a nice solution. Just added 'depth' => 1 and it was good to go. –  AndrettiMilas Feb 25 at 19:00
    
@Howdy_McGee Easily done with if ( is_page( $parentid ) ) echo ' class="current_page_item"'; –  TheDeadMedic Feb 26 at 10:44
add comment

This may not be exactly what you're looking for but I use a Frankenstein approach, it gets the job done:

First, let's check if we even need to show subpages, this will make sure this page either has children or is a child and we're not on a 404 page - if true, we will get the ancestor (parent) ID, then run WP_List_Pages twice so that we show the parent and children all in the same list.

<?php if((hasChildren($post->ID) || $post->post_parent) && !is_404()) : $ancestorID = getAncestorID(); ?>
<ul class="subpages">
    <?php wp_list_pages(array('title_li' => '', 'include' => $parentID, 'echo' => 1)); ?>
    <?php wp_list_pages(array('title_li' => '', 'child_of' => $parentID, 'echo' => 1)); ?>
</ul>
<?php endif; ?>

Into your functions.php File

/** Function to get Ancestor ID **/
function getAncestorID(){
    global $post;
    $id = $post->ID;

    if ($post->post_parent){
        $ancestors=get_post_ancestors($post->ID);
        $root=count($ancestors)-1;
        $id = $ancestors[$root];
    } 
    else if(is_singular('post') || is_archive() || (is_home() && !is_front_page())){
        $id = get_option('page_for_posts');
    }

    return $id;
}

/** Check if page Has Children **/
function hasChildren($pid) {
    $children = get_pages('child_of='.$pid);
    if($children)
        return true;
    else
        return false;
}
share|improve this answer
    
Thanks, I'm going to leave this question open for a while longer... see if there is a less clunky approach. –  AndrettiMilas Feb 25 at 16:45
add comment

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.