Related posts by author pagination not working on the production site

The code that I’m using has adapted from this example and successfully tested on my localhost but when I pass the site to a live server, the pagination crashes with wordpress permalinks set (/% postname% /) and only works with the default wp permalinks (? p = 123).
The problem is that it doesn’t show me any 404 page, but it also doesn’t let me go to the second or third pages, or any other’s if they exist.

This is a listing (custom postype) page (single-listing.php) and I have the page like this:

  1. The current single listing content;
  2. Comments;
  3. This code (to list all posts by the author of that listing);
  4. Related listings

I’ve done some research and even tried to replace “paged” because the query var for paginated archives and single posts should use “page” and followed @pietergoosen hint regarding this notice by turning On mysql.trace_mode in my local php.ini. After that I’ve restarted all services in wampp and the pagination on localhost has working, so I don’t think that this could be the problem.

This is my code:

  <?php  
  global $authordata, $post;

$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$args = array( 
    'author'            => $authordata->ID, 
    'post_type'         => 'post', 
    'post__not_in'      => array( $post->ID ), 
    'posts_per_page'    => 3,
    'paged'             => $paged
);
$authors_posts = new WP_Query( $args );

if( $authors_posts->have_posts()) : while( $authors_posts->have_posts()) : 
$authors_posts->the_post(); ?>

<a href="https://wordpress.stackexchange.com/questions/172825/<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>" ><?php the_title(); ?></a>

 <?php the_post_thumbnail( array(80,135));?>
 <?php $excerpt = get_the_excerpt(); echo string_limit_words($excerpt,40);?>
        <?php endwhile; ?>

 <?php if($authors_posts->max_num_pages)
 if(function_exists('wp_pagenavi'))
 wp_pagenavi(array(
'query' =>$authors_posts   
 )); ?>
 <?php endif; wp_reset_query(); ?>

EDIT

I’ve select the @pietergoosen answer as the one that solved my problem, but I didn’t get it why my code stop working a live server. Now, I probably will never make use of that information, but I will surely like to know why my code works on localhost (using wampserver) and not on a live server…

If you know the answer to this question, please comment. Thanks!

1 Answer
1

As I said, this whole setup you are after is not possible natively with pretty permalinks. Your setup probably works with default permalink structure as both queries (the main query and your custom query) read these permalinks in the same way. When you switch to pretty permalinks, the two queries on the single page interpret the URL differently causing one or the other to fail when you try to paginate your custom query

Single pages was never meant to be paginated in this manner, specially using pretty permalinks. I have gone and played around with a couple of ideas, and the best way to accomplish this is

  • To write your own pagination functions that can read the page number from the URL

  • Write your own function that can append the page number to the URL, something like adding /2/ to the URL of single pages.

I must stress, if you are paginating single post with <!--nextpage-->, your post will also paginate together with your custom query. Also, if your permalink structure is not set to /%postname%/, the code will fail and display an error message through wp_die()

THE CODE

Here is the code that will get the next/previous page and also add the pagenumber to the URL.

function get_single_pagination_link( $pagenum = 1 ) {
    global $wp_rewrite;

    if( is_singular() && $wp_rewrite->permalink_structure == '/%postname%/') {

        $pagenum = (int) $pagenum;

        $post_id = get_queried_object_id();
        $request = get_permalink( $post_id );

        if ( $pagenum > 1 ) {
            $request = trailingslashit( $request ) . user_trailingslashit( $pagenum );
        }

        return esc_url( $request );

    }else{

        wp_die( '<strong>The function get_single_pagination_link() requires that your permalinks are set to /%postname%/</strong>' );

    }
}

You can use this function as follow to get the link for any page in the single page when paginating your custom query

get_single_pagination_link( 'pagenumber_of_previous_or_next_page' );

Again, as I said, there is no pagination function that will be able to paginate your custom query or read pagenumbers from the URL, so you have to write your own.

Here is my idea of creating links to the next and previous pages in your custom query. If you look closely, you will see how I have used the previous declared function get_single_pagination_link() to get the links to the next and previous pages

function get_next_single_page_link ( $label = null, $max_page = 0 ) {
    global $wp_query;

    if ( !$max_page ) {
        $max_page = $wp_query->max_num_pages;
    }

    $paged = ( get_query_var('page') ) ? get_query_var('page') : 1;

    if( is_singular() ) {

        $next_page = intval($paged) + 1;

        if ( null === $label ) {
            $label = __( 'Next Page &raquo;' );
        }

        if ( ( $next_page <= $max_page ) ) {
            return '<a href="' . get_single_pagination_link( $next_page ) . '">' . $label . '</a>';
        }

    }
}

function get_previous_single_page_link( $label = null ) {

    $paged = ( get_query_var('page') ) ? get_query_var('page') : 1;

    if( is_singular() ) {

        $prev_page = intval($paged) - 1;

        if ( null === $label ) {
            $label = __( '&laquo; Previous Page' );
        }

        if ( ( $prev_page > 0 ) ) {
            return '<a href="' . get_single_pagination_link( $prev_page ) . '">' . $label . '</a>';
        }

    }

}

You can now use this two functions in your code to paginate your custom query. Both functions work exactly the same as get_next_posts_link() and get_previous_posts_link() and uses the same exact parameters, so you’ll need to keep in mind that you need to pass the $max_page parameter for your custom query

Here is your custom query with these functions.

function get_related_author_posts() {

    global $authordata, $post;

    $paged = ( get_query_var('page') ) ? get_query_var('page') : 1;

    $args = array( 
        'posts_per_page'    => 2,
        'paged'             => $paged
    );
    $authors_posts = new WP_Query( $args );

    $output="";

    if( $authors_posts->have_posts() ) {

        $output="<ul>";

        while( $authors_posts->have_posts() ) {
            $authors_posts->the_post();

            $output .= '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a>' . get_the_excerpt() . '</li>';

        }

        $output .= '</ul>';

        $output .= get_previous_single_page_link();
        $output .= get_next_single_page_link( null , $authors_posts->max_num_pages );

        wp_reset_postdata();
    }

    return $output;

}

Leave a Comment