4

The below code is for listing the custom post types itself and its children in the sidebar. The code works great but does not highlight the sub pages.

In functions.php:

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;
}}

and adding this code to the sidebar:

<ul>
<?php
$getid=get_post_top_ancestor_id(); 
#echo $getid;
global $post;
$post=get_post($getid);
setup_postdata($post);
?>
<?php
if (is_single($post->ID)) {$pg_li .="current_page_item";}
else {
$pg_li .="page_item";}
?>
<h3><?php the_title();?></h3>
<p></p>
<li class="<?php echo $pg_li; ?>">
<a href="<?php the_permalink(); ?>">BIOGRAPHY</a>
</li>
<li class="<?php echo $pg_li; ?>">
<?php
$args=array(
'post_type'=>'artists',
'child_of'=>$getid ,
'sort_column'=>'menu_order',
'hierarchical' => 1,
'title_li'=>__('')
);
wp_list_pages( $args );
wp_reset_query();
?></li>
</ul>

I am not familiar with PHP, and a friend helped me to write this code. So what am I missing to highlight the current sub menu of that custom post type?

5
  • Do you actually have a unique style in your css for .current_page_item? Commented Nov 27, 2012 at 9:00
  • @JohannesPille yes, i have..
    – sez
    Commented Nov 28, 2012 at 18:25
  • 1
    Would it be possible to list them with a custom navigation menu instead of the code you used? Reason I ask is because if you can replace it with a custom navigation menu you can use: vayu.dk/…
    – user2015
    Commented Jan 24, 2013 at 13:13
  • 1
    Can we see the rendered page? Commented May 16, 2013 at 14:41
  • There is a hack on the link: mark-leong.com/…, Or checkout this one kucrut.org/wp_list_pages-for-custom-post-types
    – Kumar
    Commented Apr 1, 2014 at 8:14

2 Answers 2

1

The problem with this code is that the query is being altered and current_page_item is being lost. This is the part causing problems.

$post = get_post( $getid );
setup_postdata( $post );

If you comment out those two lines you'll see that current_page_item appears.

There are also some secondary problems with this code that have no bearing on the main problem.

  1. <p></p> should not exist as a child element of <ul>. Only <li> is allowed.
  2. <h3>...</h3> also should not exist as a child element of <ul> for the same reasons as #1.
  3. The if statement setting the CSS class for the "Biography" link will return true on any single page, not just the parent page.
  4. wp_list_pages() outputs a list of <li>...</li> tag pairs so it doesn't need to be wrapped with another pair of <li>...</li> tags.

The following code corrects all the issues.

<?php
$getid = get_post_top_ancestor_id(); 
global $post;
?>
<h3><?php echo get_the_title( $getid );?></h3>
<ul>
    <?php
    if ( $post->ID == $getid ) {
        $pg_li .= "current_page_item";
    } else {
        $pg_li .= "page_item";
    }
    ?>  
    <li class="<?php echo $pg_li; ?>">
        <a href="<?php echo get_permalink( $getid ); ?>">BIOGRAPHY</a>
    </li>
    <?php
    $args=array(
        'post_type' => 'artists',
        'child_of' => $getid,
        'sort_column' => 'menu_order',
        'hierarchical' => 1,
        'title_li' => __('')
    );
    wp_list_pages( $args );
    ?>
</ul>
1

There is a fix coming up for the same, here is the ticket: https://core.trac.wordpress.org/changeset/27755

In case you need it urgently, you can give this a try

Original Answer by @goldenapples, here is the link:

Dynamic navigation for custom post type (pages)

function wp_list_post_types( $args ) {
$defaults = array(
    'numberposts'  => -1,
    'offset'       => 0,
    'orderby'      => 'menu_order, post_title',
    'order'      => 'ASC',
    'post_type'    => 'page',
    'depth'        => 0,
    'show_date'    => '',
    'date_format'  => get_option('date_format'),
    'child_of'     => 0,
    'exclude'      => '',
        'include'      => '',
    'title_li'     => __('Pages'),
    'echo'         => 1,
    'link_before'  => '',
    'link_after'   => '',
    'exclude_tree' => '' );

$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );

$output = '';
$current_page = 0;

// sanitize, mostly to keep spaces out
$r['exclude'] = preg_replace('/[^0-9,]/', '', $r['exclude']);

// Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
$exclude_array = ( $r['exclude'] ) ? explode(',', $r['exclude']) : array();
$r['exclude'] = implode( ',', apply_filters('wp_list_post_types_excludes', $exclude_array) );

// Query pages.
$r['hierarchical'] = 0;
$pages = get_posts($r);

if ( !empty($pages) ) {
    if ( $r['title_li'] )
        $output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';

    global $wp_query;
    if ( ($r['post_type'] == get_query_var('post_type')) || is_attachment() )
        $current_page = $wp_query->get_queried_object_id();
    $output .= walk_page_tree($pages, $r['depth'], $current_page, $r);

    if ( $r['title_li'] )
        $output .= '</ul></li>';
}

$output = apply_filters('wp_list_pages', $output, $r);

if ( $r['echo'] )
    echo $output;
else
    return $output;
 }

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.