1

I have this snippet

<ul>
    <?php
    global $id;
    wp_list_pages( array(
        'title_li'    => '',
        'depth'        => 1,
        'child_of'    => $id,
        'sort_column' => 'post_title',
        'show_date'   => 'modified',
        'date_format' => $date_format
    ) );
    ?>
</ul>

But how would I add this...

<?php comments_number( 'no responses', 'one response', '% responses' ); ?>

So the number of comments are displayed after each page title?

1 Answer 1

1

A custom walker can be passed to wp_list_pages() using the $walker parameter.

Here is a custom walker named WPSE_Walker_Page_Comment_Count() which is based on the default page walker, Walker_Page(). We're only overriding the start_el() method in this case. The output has been customized to include the comment count.

First, add the walker code to your theme's functions.php or to a plugin:

class WPSE_Walker_Page_Comment_Count extends Walker_Page {
    // Copied from Walker_Page::start_el() core version v4.7.4.
    /**
     * Outputs the beginning of the current element in the tree.
     *
     * @see Walker::start_el()
     * @since 2.1.0
     * @access public
     *
     * @param string  $output       Used to append additional content. Passed by reference.
     * @param WP_Post $page         Page data object.
     * @param int     $depth        Optional. Depth of page. Used for padding. Default 0.
     * @param array   $args         Optional. Array of arguments. Default empty array.
     * @param int     $current_page Optional. Page ID. Default 0.
     */
    public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
        if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) {
            $t = "\t";
            $n = "\n";
        } else {
            $t = '';
            $n = '';
        }
        if ( $depth ) {
            $indent = str_repeat( $t, $depth );
        } else {
            $indent = '';
        }

        $css_class = array( 'page_item', 'page-item-' . $page->ID );

        if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
            $css_class[] = 'page_item_has_children';
        }

        if ( ! empty( $current_page ) ) {
            $_current_page = get_post( $current_page );
            if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) {
                $css_class[] = 'current_page_ancestor';
            }
            if ( $page->ID == $current_page ) {
                $css_class[] = 'current_page_item';
            } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {
                $css_class[] = 'current_page_parent';
            }
        } elseif ( $page->ID == get_option('page_for_posts') ) {
            $css_class[] = 'current_page_parent';
        }

        /**
         * Filters the list of CSS classes to include with each page item in the list.
         *
         * @since 2.8.0
         *
         * @see wp_list_pages()
         *
         * @param array   $css_class    An array of CSS classes to be applied
         *                              to each list item.
         * @param WP_Post $page         Page data object.
         * @param int     $depth        Depth of page, used for padding.
         * @param array   $args         An array of arguments.
         * @param int     $current_page ID of the current page.
         */
        $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );

        if ( '' === $page->post_title ) {
            /* translators: %d: ID of a post */
            $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
        }

        $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before'];
        $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after'];

        // Get the comment count for the page.
        $comments_number = get_comments_number( $page->ID );
        if ( 0 == $comments_number ) {
            $comments_number_output = __( '&nbsp;&mdash; No Repsonses', 'text_domain' );
        } else {
            $comments_number_output = sprintf(
                /* translators: number of comments */
                _nx(
                    '&nbsp;&mdash; %1$s Response',
                    '&nbsp;&mdash; %1$s Responses',
                    $comments_number,
                    'comments title',
                    'text_domain'
                ),
                number_format_i18n( $comments_number )
            );
        }
        $output .= $indent . sprintf(
            '<li class="%s"><a href="%s">%s%s%s%s</a>',
            $css_classes,
            get_permalink( $page->ID ),
            $args['link_before'],
            /** This filter is documented in wp-includes/post-template.php */
            apply_filters( 'the_title', $page->post_title, $page->ID ),
            $args['link_after'],
            sprintf( '<span class="comment-count">%s</span>', // Append comment count.
                $comments_number_output
            )
        );

        if ( ! empty( $args['show_date'] ) ) {
            if ( 'modified' == $args['show_date'] ) {
                $time = $page->post_modified;
            } else {
                $time = $page->post_date;
            }

            $date_format = empty( $args['date_format'] ) ? '' : $args['date_format'];
            $output .= " " . mysql2date( $date_format, $time );
        }
    }
}

Then in your template, call wp_list_pages() like this:

<ul><?php
    wp_list_pages( array(
        'title_li'    => '',
        'depth'       => 1,
        'child_of'    => get_the_ID(),
        'sort_column' => 'post_title',
        'show_date'   => 'modified',
        'date_format' => $date_format,
        'walker'      => new WPSE_Walker_Page_Comment_Count(),
    ) );
?></ul>

Note that I used get_the_ID(), which is cleaner than using the global $id variable. Also, $date_format was never defined in your original code. The most important part is the addition of the $walker parameter, which tells wp_list_pages() to use our custom walker to generate output.

Example output (formatted for legibility):

<ul>
    <li class="page_item page-item-1090">
        <a href="http://example.com/parent-page/child-page-01/">Child Page 01<span class="comment-count">&nbsp;— 1 Response</span></a>
    </li>
    <li class="page_item page-item-1092">
        <a href="http://example.com/parent-page/child-page-02/">Child Page 02<span class="comment-count">&nbsp;— No Responses</span></a>
    </li>
    <li class="page_item page-item-1094 page_item_has_children">
        <a href="http://example.com/parent-page/child-page-03/">Child Page 03<span class="comment-count">&nbsp;— 2 Responses</span></a>
    </li>
    <li class="page_item page-item-1096">
        <a href="http://example.com/parent-page/child-page-04/">Child Page 04<span class="comment-count">&nbsp;— No Responses</span></a>
    </li>
    <li class="page_item page-item-1098">
        <a href="http://example.com/parent-page/child-page-05/">Child Page 05<span class="comment-count">&nbsp;— No Responses</span></a>
    </li>
</ul>
0

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.