سؤال

I am using get_posts and get_comments to build several loops on the page, at which I am having some issues in pagination.

I have the global posts per page option (Settings > Reading) set to 10, and this seems to vary the problem. As of now, I can easily get to Page 2 - http://dev.ashfame.com/author/ashfame/page/2/, but Page 3 returns a 404.

If I lower the global value, I get to have more paginated pages but not all (lesser number than how many there should be).

Update: I just tried setting my custom setting as 2 (and the global one too), and WordPress should paginate until page 4 (I have 7 items to show) but now it does but also page 5 & 6. 7 gives 404. Why? How do I troubleshoot this thing now?

Progress: @t31os helped me figure out that its the WP default query on the page which is setting up the pagination for that page. Now I can think of one way to kill the default WP query on that page (but how?) and then how would I further paginate the author.php page? Or is there any other way of doing it?

Current code:

<?php

            $author_details = $wp_query->get_queried_object();

            // Posts Per Page option
            // $ppp = get_option('posts_per_page');
            $ppp = 1; //custom setting, if you want to obey the global setting here, comment this line and uncomment the above line

            if (!is_paged()) {
                $custom_offset = 0;
            } else {
                $custom_offset = $ppp*($paged-1);
            }

            echo '<h1>Author ID : '.$author_details->ID.', Page : '.$paged.', Custom Offset : '.$custom_offset.'</h1>';

            ?>

            <h2>Articles</h2>

            <?php
            $args = array(
            'numberposts' => $ppp,
            'offset' => $custom_offset,
            'category' => 7,
            'author' => $author_details->ID
            );

            $posts_data = get_posts( $args );

            // print_r($posts_data);

            if ( count( $posts_data ) > 0 ) {               
                echo '<ul>';                
                foreach ( $posts_data as $post ) {                      
                    echo '<li><a href="'.get_permalink( $post->ID ).'">'.$post->post_title.'</a></li>';
                }               
                echo '</ul>';
            } else {
                echo '<p>No articles by this user</p>';
            }           
            ?>

            <h2>Journals</h2>

            <?php
            $args = array(
            'numberposts' => $ppp,
            'offset' => $custom_offset,
            'category' => 6,
            'author' => $author_details->ID
            );
            $posts_data = get_posts( $args );

            // print_r($posts_data);

            if ( count( $posts_data ) > 0 ) {               
                echo '<ul>';                
                foreach ( $posts_data as $post ) {                      
                    echo '<li><a href="'.get_permalink( $post->ID ).'">'.$post->post_title.'</a></li>';
                }               
                echo '</ul>';
            } else {
                echo '<p>No journals by this user</p>';
            }
            ?>

            <h2>Questions</h2>

            <?php
            $args = array(
            'numberposts' => $ppp,
            'offset' => $custom_offset,
            'category' => 3, // parent category ID is enough
            'author' => $author_details->ID
            );
            $posts_data = get_posts( $args );

            // print_r($posts_data);

            if ( count( $posts_data ) > 0 ) {               
                echo '<ul>';                
                foreach ( $posts_data as $post ) {                      
                    $category_array = get_the_category( $post->ID );
                    $category_name = $category_array[0]->name;
                    $category_permalink = get_category_link( $category_array[0]->term_id );
                    echo '<li><a href="'.get_permalink( $post->ID ).'">'.$post->post_title.'</a>
                    <br />In: <a href="'.$category_permalink.'">'.$category_name.'</a><br />'.get_comments_number( $post->ID ).' Answers</li>';
                }               
                echo '</ul>';
            } else {
                echo '<p>No questions by this user</p>';
            }
            ?>

            <h2>Answers</h2>

            <?php
            $args = array(
            'user_id' => $author_details->ID,
            'number' => $ppp,
            'offset' => $custom_offset,
            'status' => 'approve'
            );
            $answers_list = get_comments( $args );

            // print_r($answers_list);

            if ( count( $answers_list ) > 0 ) {
                $date_format = get_option( 'date_format' );
                echo '<ul>';
                foreach ( $answers_list as $answer ) {
                    echo '<li>Answer: '.substr( $answer->comment_content, 0, 20 ).'..<br />'.date( $date_format, strtotime( $answer->comment_date ) ).'<br />Question: <a href="'.get_permalink( $answer->comment_post_ID ).'">'.get_the_title( $answer->comment_post_ID ).'</a></li>';
                }
                echo '</ul>';
            } else {
                echo '<p>No answers by this user</p>';
            }
            ?>
هل كانت مفيدة؟

المحلول

t31os says: [See edit history for previous code and comments]

Using Ajax to paginate your queries

I've put together some code that will fetch your posts and comments via ajax using simple prev/next navigation via ajax.

1) Replace all the code you posted in your author.php with the following..

<?php $cat_settings = array( 'Articles' => 7, 'Journals' => 6, 'Questions' => 3 ); ?>
<?php do_action( 'author_ajax_catposts', $cat_settings ); ?>

2) Create a Javascript file in your theme's directory called authorposts.js and place the following code into that file.

jQuery(document).ready( function($) {

    if( 'undefined' == typeof( aacVars ) )
        return;

    $('.aacnav').click(function() {

        var r = $( $(this).attr('href') );
        var a = $( $(this).attr('href') + '-ap' );
        var c = this.className.split(' ');

        if( 
            'undefined' == typeof( c ) || 
            'undefined' == typeof( r ) || 
            'undefined' == typeof( a ) 
        )
            return false;

        var d = { 
            action:      aacVars.posts_action, 
            _ajax_nonce: aacVars.nonce,
            author:      aacVars.author,
            category:    $(this).attr('href')
        };

        p = parseInt( a.text() );
        c = c.pop();

        switch( c ) {
            case 'aacnext':
                if( r.children('p.nomore').length )
                    return false;
                d.page = p + 1;
            break;
            case 'aacprev':
                if( p < 2 )
                    return false;
                d.page = p - 1;
            break;
            default:
                return false;
        }

        $.post( aacVars.ajaxpth, d, function( res ) {
            if( '-1' == res ) {
                alert( 'auth failed' );
                return false;
            }
            $( r ).html( res );
            $( a ).text( d.page );
        });

        return false;
    });

    $('.aacnavc').click(function() {

        var r = $( '#aac-comments' );
        var n = $( '#aac-comments-ap' );
        var l = $(this).attr('href');

        if( 
            'undefined' == typeof( n ) || 
            'undefined' == typeof( r ) 
        )
            return false;

        var d = { 
            action:      aacVars.comments_action, 
            _ajax_nonce: aacVars.nonce,
            author:      aacVars.author
        };

        p = parseInt( n.text() );

        switch( l ) {
            case '#next':
                if( r.children('p.nomore').length )
                    return false;
                d.page = p + 1;
            break;
            case '#prev':
                if( p < 2 )
                    return false;
                d.page = p - 1;
            break;
            default:
                return false;
        }

        $.post( aacVars.ajaxpth, d, function( res ) {
            if( '-1' == res ) {
                alert( 'auth failed' );
                return false;
            }
            r.html( res );
            $( n ).text( d.page );
        });

    });

});

3) Copy the following code into your theme's functions.php file.

class Author_Ajax_Cats {

    private $posts_per_page    = 3;
    private $comments_per_page = 1;
    private $posts_action      = 'aac-posts';
    private $comments_action   = 'aac-comments';
    private $js                = array();

    public function __construct() {

        add_action( 'parse_request',                            array( $this, 'aac_parse_request' ) );
        add_action( 'wp_ajax_nopriv_' . $this->posts_action,    array( $this, 'aac_ajax_posts' ) );
        add_action( 'wp_ajax_' .        $this->posts_action,    array( $this, 'aac_ajax_posts' ) );
        add_action( 'wp_ajax_nopriv_' . $this->comments_action, array( $this, 'aac_ajax_comments' ) );
        add_action( 'wp_ajax_' .        $this->comments_action, array( $this, 'aac_ajax_comments' ) );
        add_action( 'wp_enqueue_scripts',                       array( $this, 'aac_enqueue_scripts' ) );
        add_action( 'author_ajax_catposts',                     array( $this, 'aac_print_posts' ) );
    }
    public function aac_parse_request( $wp ) {

        if( !isset( $wp->query_vars['author_name'] ) || is_admin() )
            return;

        $wp->query_vars['paged'] = 1;

    }
    private function setup_js_vars() {

        global $wp_query;

        $this->js['author']          = $wp_query->get_queried_object_id();
        $this->js['posts_action']    = $this->posts_action;
        $this->js['comments_action'] = $this->comments_action;
        $this->js['nonce']           = wp_create_nonce( 'noncekey' );
        $this->js['ajaxpth']         = admin_url( 'admin-ajax.php' );
    }
    public function aac_enqueue_scripts() {

        if( !is_author() )
            return;

        $this->setup_js_vars();

        wp_register_script( 'author-ajax', get_bloginfo('stylesheet_directory') . '/authorposts.js', array( 'jquery' ), time(), true );
        wp_localize_script( 'author-ajax', 'aacVars', $this->js );
        wp_enqueue_script( 'author-ajax' );
    }
    public function aac_ajax_comments() {

        if( !isset( $_POST['page'] ) || !isset( $_POST['author'] ) )
            die;

        check_ajax_referer( 'noncekey' );

        $authID = absint( $_POST['author'] );
        $paged  = absint( $_POST['page'] );

        $args = array(
            'user_id' => $authID,
            'number'  => $this->comments_per_page,
            'offset'  => ( ( $paged - 1 ) * $this->comments_per_page ),
            'status'  => 'approve',
            'type'    => 'comment'
        );

        $answers_list = get_comments( $args );
        if( empty( $answers_list ) ) {
            printf( '<p class="nomore">%s</p>', __( 'No more answers by this user.' ) );
            die;
        }
        $_comment_walk = new Walker_Comment;

        echo '<ul>';
        $_comment_walk->paged_walk( $answers_list, 0, 1, $this->comments_per_page, array( 
            'style' => 'ul', 
            'avatar_size' => 15, 
            'max_depth' => 1, 
            'callback' => array( $this, 'author_comment_walker' ) 
        ) );
        echo '</ul>';

        die;
    }
    public function aac_ajax_posts() {

        if( !isset( $_POST['page'] ) || !isset( $_POST['category'] ) || !isset( $_POST['author'] ) )
            die;

        check_ajax_referer( 'noncekey' );

        $catID  = absint( str_replace( '#aac-', '', $_POST['category'] ) );
        $authID = absint( $_POST['author'] );
        $paged  = absint( $_POST['page'] );

        $args = array(
            'paged'       => $paged,
            'numberposts' => $this->posts_per_page,
            'author'      => $authID,
            'cat'         => $catID
        );
        $posts = get_posts( $args );

        if( empty( $posts ) )
            die( sprintf( '<p class="nomore">%s</p>', __( 'No more posts.' ) ) );

        $this->do_posts( $posts );

        die;
    }
    public function aac_print_posts( $cats = array() ) {

        //get_the_term_list( $post->ID, 'category', '<ul><li>', '</li><li>', '</li></ul>' )

        foreach( $cats as $heading => $id ) {
            $args = array( 
                'cat'         => $id,
                'paged'       => 1, // Always the first page on load
                'numberposts' => $this->posts_per_page, 
                'author'      => $this->js['author']
            );
            $posts = get_posts( $args );

            printf( '<h2>%s</h2>', $heading );

            if( empty( $posts ) ) {
                printf( '<div><p class="nomore">%s</p></div>', __( 'No posts.' ) );
                continue;
            }

            printf( '<div id="aac-%d" class="aac-result">', $id );

            $this->do_posts( $posts );

            printf( '</div><div>' );
            printf( '<p class="alignright">Page: <span id="aac-%1$d-ap">1</span></p><p class="alignleft"><a class="aacnav aacprev" href="#aac-%1$d">%2$s</a> <a class="aacnav aacnext" href="#aac-%1$d">%3$s</a></p>', $id, __('Previous'), __('Next') );
            printf( '<br class="clear" /></div>' );
        }
        ?>

        <h2>Answers</h2>

        <?php
        $args = array(
            'user_id' => $this->js['author'],
            'number'  => $this->comments_per_page,
            'status'  => 'approve',
            'type'    => 'comment'
        );
        $answers_list = get_comments( $args );
        if( empty( $answers_list ) ){
            printf( '<p>%s</p>', __( 'No answers by this user' ) );
            return;
        }
        $_comment_walk = new Walker_Comment;

        printf( '<div id="aac-comments"><ul>' );

        $_comment_walk->paged_walk( $answers_list, 0, 1, $this->comments_per_page, array( 
            'style' => 'ul', 
            'avatar_size' => 15, 
            'max_depth' => 1, 
            'callback' => array( $this, 'author_comment_walker' ) 
        ) );

        printf( '</ul></div><div><p class="alignright">Page: <span id="aac-comments-ap">1</span></p><p class="alignleft"><a class="aacnavc" href="#prev">%s</a> <a class="aacnavc" href="#next">%s</a></p><br class="clear" /></div>', __('Prev'), __('Next') );
    }
    private function do_posts( $posts, $term_id = 0 ) {

        echo '<ul>';
        foreach( $posts as $post )
            printf( '<li><a href="%s">%s</a></li>', get_permalink( $post->ID ), get_the_title( $post->ID ) );
        echo '</ul>';

    }
    public function author_comment_walker( $comment, $args, $depth ) {

        $GLOBALS['comment'] = $comment; 
        ?>

        <li>
            <div id="comment-<?php comment_ID(); ?>">
                <div>
                    <?php echo get_avatar( $comment, $args['avatar_size'], $default = '<path_to_url>' ); ?> <?php echo get_comment_author_link(); ?> answered 
                    <a href="<?php echo get_permalink( $comment->comment_post_ID ); ?>"><?php echo get_the_title( $comment->comment_post_ID ); ?></a> on <a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>"><?php printf( __( '%1$s at %2$s' ), get_comment_date(),  get_comment_time() ); ?></a>
                    <?php //edit_comment_link( __( '(Edit)' ),'  ','' ); ?>
                </div>
                <?php // comment_text() ?>
                <p><?php comment_excerpt(); ?></p>
            </div>
        <?php
    }
}
$aac = new Author_Ajax_Cats;

4) Fire up an author page and see how the results look and to check my code works for you.

How it looks locally with test data.

Click to view larger version, scaled down for the answer

Live demo of the code in action:** (test site)

http://t31os.onatha.com/author/t31os/

5) Provide some feedback.. :)

I hope that helps...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى wordpress.stackexchange
scroll top