• Resolved Abel Thomas

    (@abelthomas)


    Hi guys,

    So I’ve been troubleshooting this for days now, and have attempted several stackexchange/stackoverflow/google solutions to no avail.

    Essentially what I’m struggling with is pagination in my archive.php file. The page loads fine (no white screen of death), and the pagination displays the correct number of pages, but any page past #1 gives a 404 error. Here is all the relevant code:

    <?php // set up query args
    $paged = ( get_query_var( 'paged' ) ) ? get_query_var('paged') : 1;
    $query_args = array(
    	'paged' => $paged,
    	'post_status' => 'publish',
    	'posts_per_page' => 1, // for testing purposes
    	'post_type' => get_query_var('post_type')
    	);
    
    // begin custom loop
    $loop = new WP_Query($query_args);
    if ($loop->have_posts()) : ?>
    
    	<div class="group section">
    	<?php while ($loop->have_posts()) : $loop->the_post();
    		// do loopy stuff
    	endwhile; wp_reset_postdata(); 
    
    	// pagination
    	at_archive_pagination(array('total' => $loop->max_num_pages)); ?>

    And here is that pagination function (housed in functions.php and copied mostly from a default WP theme pagination function):

    function at_archive_pagination($args = '') {
    	$defaults = array(
    		'total' => $GLOBALS['wp_query']->max_num_pages
    		);
    	$args = wp_parse_args($args, $defaults);
    	extract($args);
    
    	// Don't print empty markup if there's only one page.
    	if ( $total < 2 ) {
    		return;
    	}
    
    	$paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
    	$pagenum_link = html_entity_decode( get_pagenum_link() );
    	$query_args   = array();
    	$url_parts    = explode( '?', $pagenum_link );
    
    	if ( isset( $url_parts[1] ) ) {
    		wp_parse_str( $url_parts[1], $query_args );
    	}
    
    	$pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
    	$pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
    
    	$format  = $GLOBALS['wp_rewrite']->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
    	$format .= $GLOBALS['wp_rewrite']->using_permalinks() ? user_trailingslashit( 'page/%#%', 'paged' ) : '?paged=%#%';
    
    	// Set up paginated links.
    	$links = paginate_links( array(
    		'base'     => $pagenum_link,
    		'format'   => $format,
    		'total'    => $total,
    		'current'  => $paged,
    		'mid_size' => 1,
    		'add_args' => array_map( 'urlencode', $query_args ),
    		'prev_text' => 'Previous',
    		'next_text' => 'Next',
    	) );
    
    	if ( $links ) : ?>
    	<nav class="navigation paging-navigation" role="navigation">
    		<h1 class="screen-reader-text"><?php _e( 'Posts navigation', 'twentyfourteen' ); ?></h1>
    		<div class="pagination loop-pagination">
    			<?php echo $links; ?>
    		</div><!-- .pagination -->
    	</nav><!-- .navigation -->
    	<?php endif;
    }

    Any help or suggestions are greatly appreciated, thanks!

Viewing 1 replies (of 1 total)
  • Thread Starter Abel Thomas

    (@abelthomas)

    Turns out I’ve solved my own problem. Instead of creating a custom WP_Query in archive.php, I instead altered the main query using the ‘pre_get_posts’ hook. Here’s the code that does that (located in functions.php):

    add_action('pre_get_posts', 'at_modify_archive_query');
    function at_modify_archive_query( $query ){
    	// only modify query on frontend pages && if is main query
    	if ( is_admin() || !$query->is_main_query() )
    		return;
    
    	// modify post count on any archive
    	if ( $query->is_archive )
    		$query->set('posts_per_page',6);
    }

    This executes before the initial database call is made, and doesn’t require an additional database call (like WP_Query does). And the best part, all the WP pagination functions work flawlessly (paginate_links(), the_posts_pagination(), next_posts_link(), etc.).

    Hope this helps someone else!

Viewing 1 replies (of 1 total)

The topic ‘Broken pagination using custom wp_query loop’ is closed to new replies.