I have a set of custom post types with the capability_type argument set to 'page'

I want to include these in wp_list_pages() or similar so I can use the dynamic classes (such as .current_page_item and the like).

I've read this post but I'm not sure it's exactly what I'm looking for, can anyone help me out with a code sample / more in-depth explanation.


2 Answers 2


The wp_list_pages() function calls get_pages(), which can't be easily overridden with a different post type. Here's a basic modification of that function which calls get_posts() instead. This takes basically the same arguments as wp_list_pages, with one additional: *post_type* (set as the name of your post type).

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;
        return $output;

Note: its mostly copy-pasted from source. There's certainly a few arguments left in there that aren't doing anything and there might well be some use cases I haven't thought of that would break it. It works, surprisingly, though, with both hierarchical and non-hierarchical post types, though...

  • Hi Goldenapples, this is great & displays the posts in the correct format, but doesn't pass the class current_page_item when you go to a page in the list. Any help would be really appreciated! Oct 26, 2010 at 8:25
  • 2
    Ah... There was a test for is_page() left in there. I replaced it with if ($r['post_type'] == get_query_var('post_type')). It adds the correct 'current_page_item' class now. I edited the code above. Oct 26, 2010 at 16:29

@goldenapples: Excellent post! I was searching for this and got here. One thing I noticed is the orderby was not working properly, and got it fixed by adding the following line to the default arguments:

'order' => 'ASC',

Thanks, Camilo

Your Answer

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

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