3

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="<?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!

  • wp_pagenavi is a third party plugin. Pleask to the developer. Thirk party plugins are off-topic. – cybmeta Dec 20 '14 at 19:01
  • @cybmeta this is not a problem of wp_pagenavi! Did you pay attention to all the references that I made on the question? Please read well before commenting like this... – Alex Dec 20 '14 at 19:10
  • You are asking the wrong question here. I have tested all scenarios, and came to the conclusion, you will have to rewrite something like /%pagenumber%/ (which does not really exists) to single page URL's as manually writing mysite.com/%postname%/2/ works, then you'll need to create a pagination function to work with this new structure. There is just no easy way around this. Single pages where never meant to be paginated like this – Pieter Goosen Dec 20 '14 at 19:27
  • Are you sure it is not the problem? Sure? Maybe not it is not the problem, maybe the problem is your implementation of wp_pagenavi which is also off-topic. If none of these options are the problem you will have to clarify it. – cybmeta Dec 20 '14 at 19:31
  • I'm lost... can you be more specific? – Alex Dec 20 '14 at 19:32
2

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;

}
  • This is perfect and works fine, thanks! I just added 'author' => $authordata->ID, 'post_type' => 'post', 'post__not_in' => array( $post->ID ),, but I still dind't get why my code dind't worked on a live server... – Alex Dec 21 '14 at 23:45
  • O crap yes, I've removed those parts for testing purposes, totally forgot to add them back :-). It is strange, on my test install it also did not work. I suggest that you compare your htaccess files – Pieter Goosen Dec 22 '14 at 3:54
  • this is my local htaccess code # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /loc/ RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /loc/index.php [L] </IfModule> # END WordPress and it's precisely the same on the production site. This sound like a well covered mystery... :-) – Alex Dec 22 '14 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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