Why pagination is not working and gives a 404 error on the wordpress site?
Asked Answered
P

3

6

Good day! The problem is this: in the template category(the archive) the pagination is not working, when you click on page 2 of the 404 error. Please help do not understand how to solve it, already all head broke

My loop:

<?php
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$arg = array(
  'cat' => get_queried_object_id(),
  'post_type'=>'post',
  'posts_per_page'=>9,
  //'order'=>'desc',
  'paged' => $paged,
  );
$query = new WP_query($arg);
if($query->have_posts()) : ?>
<section class="blog">
  <?php
  echo '<div class="row">';
  $i=0;
  $formcreated=false;
  while( $query->have_posts() ) :
    $query->the_post();
    // display post 
   endwhile;
   wp_reset_postdata();
endif;
?>

<div class="pagination">
  <?php
       if (function_exists('custom_pagination')) {
         custom_pagination($query->max_num_pages,"",$paged);
       }
     ?>
   <?php wp_reset_postdata(); ?>
</div>

And my custom pagination:

function my_post_queries( $query ) {
    // do not alter the query on wp-admin pages and only alter it if it's the main query
    if (!is_admin() && $query->is_main_query()){

        // alter the query for the home and category pages


        if(is_category()){
            $query->set('posts_per_page', 1);
            $query->set('post_type','product');
        }

    }
}
add_action( 'pre_get_posts', 'my_post_queries' );

function custom_pagination($numpages = '', $pagerange = '', $paged='') {

  if (empty($pagerange)) {
    $pagerange = 2;
  }

  /**
   * This first part of our function is a fallback
   * for custom pagination inside a regular loop that
   * uses the global $paged and global $wp_query variables.
   *
   * It's good because we can now override default pagination
   * in our theme, and use this function in default queries
   * and custom queries.
   */
  global $paged;
  if (empty($paged)) {
    $paged = 1;
  }
  if ($numpages == '') {
    global $wp_query;
    $numpages = $wp_query->max_num_pages;
    if(!$numpages) {
        $numpages = 1;
    }
  }

  /**
   * We construct the pagination arguments to enter into our paginate_links
   * function.
   */
  $pagination_args = array(
    'base'            => get_pagenum_link(1) . '%_%',
    'format'          => 'page/%#%',
    'total'           => $numpages,
    'current'         => $paged,
    'show_all'        => False,
    'end_size'        => 1,
    'mid_size'        => $pagerange,
    'prev_next'       => True,
    'prev_text'       => __('&#60;'),
    'next_text'       => __('&#62;'),
    'type'            => 'plain',
    'add_args'        => false,
    'add_fragment'    => ''
  );

  $paginate_links = paginate_links($pagination_args);

  if ($paginate_links) {
    echo "<nav class='custom-pagination'>";
      echo $paginate_links;
    echo "</nav>";
  }

}
Pouched answered 12/2, 2017 at 15:12 Comment(6)
Possible duplicate of Pagination on custom wp_query in WordPress takes to 404 error pageTurbojet
#22364794Turbojet
@Turbojet it does seem to my untrained eye that present OP is already using that trick, at least partly, in the code we see here?Henrion
He has posts per page 1 in the second set of code, presumably that is inside the functions.php, and he's got 9 posts per page on the loop args. Do you see that the numbers don't match. Also, he wants all categories to have the same pagination or just the one used in the custom loop? So he needs to use conditionals more specific than is_category and the check to see if it's not built in (a cpt) is not the way you do it.Turbojet
Okay. I see what he means. When the posts per page in reading settings are greater than the posts in the custom query, then you get a 404. I will answer this question later today.Turbojet
I updated my answer with pre_get_posts instead of parse_query. Works better and now you can have pagination for the CPT and different, if you want, for categories under that.Turbojet
T
19

Since this has come up in two different forums lately, I am answering this.

If you use custom pagination, such as the one you're using which appears to come from http://callmenick.com/post/custom-wordpress-loop-with-pagination but it happens with Genesis child themes too because the parent numbered pagination is what people what.

Why do you get a 404 page? The Custom pagination in the callmenick.com and Genesis (genesis_posts_nav) is for the main query and so if your pagination for your different query is under the posts per page in your reading settings (which is set for the main query), then you will get a 404 on page 2.

Every front end page request on a WordPress site produces a main query. The template that WordPress decides to load is based on the results of that main query (you can see the order that WordPress does these things by looking at the Action Reference page). Despite the fact that you never output the results of that query, it's still run, and in the case of paginated archives, this is an issue if you're trying to use that pagination for a different query. — Milo https://wordpress.stackexchange.com/a/120963/64742

You don't see this question a lot because many just build the pagination for that loop instead of re-using it from the functions.php file or a parent theme. You can learn that here: https://codex.wordpress.org/Function_Reference/paginate_links

Let's start from the top and whenever you code, turn on debug in wp-config.php


A basic custom loop in my cpt archive.

archive-product.php

 <?php $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;

  $product_args = array(
      'post_type' => 'product',
      'posts_per_page' => 2, //the same as the parse_query filter in our functions.php file
      'paged' => $paged,
      'page' => $paged
    );

  $product_query = new WP_Query( $product_args ); ?>

  <?php if ( $product_query->have_posts() ) : ?>

    <!-- the loop -->
    <?php while ( $product_query->have_posts() ) : $product_query->the_post(); ?>
      <article class="loop">
        <h3><?php the_title(); ?></h3>
        <div class="content">
          <?php the_excerpt(); ?>
        </div>
      </article>
    <?php endwhile; ?>
    <!-- end of the loop -->


    <!-- pagination here -->
    <?php
       if (function_exists( 'custom_pagination' )) :
          custom_pagination( $product_query->max_num_pages,"",$paged );
      endif;
   ?>


  <?php wp_reset_postdata(); ?>

  <?php else:  ?>
    <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
  <?php endif; ?>

In your functions.php file:

Learn about conditionals. https://codex.wordpress.org/Conditional_Tags https://codex.wordpress.org/Function_Reference/is_post_type_archive

/** 
 * Posts per page for CPT archive
 * prevent 404 if posts per page on main query
 * is greater than the posts per page for product cpt archive
 *
 * thanks to https://sridharkatakam.com/ for improved solution!
 */

function prefix_change_cpt_archive_per_page( $query ) {
    
    //* for cpt or any post type main archive
    if ( $query->is_main_query() && ! is_admin() && is_post_type_archive( 'product' ) ) {
        $query->set( 'posts_per_page', '2' );
    }

}
add_action( 'pre_get_posts', 'prefix_change_cpt_archive_per_page' );

/**
 * 
 * Posts per page for category (test-category) under CPT archive 
 *
*/
function prefix_change_category_cpt_posts_per_page( $query ) {

    if ( $query->is_main_query() && ! is_admin() && is_category( 'test-category' ) ) {
        $query->set( 'post_type', array( 'product' ) );
        $query->set( 'posts_per_page', '2' );
    }

}
add_action( 'pre_get_posts', 'prefix_change_category_cpt_posts_per_page' );


/**
*
* custom numbered pagination 
* @http://callmenick.com/post/custom-wordpress-loop-with-pagination
* 
*/
function custom_pagination( $numpages = '', $pagerange = '', $paged='' ) {

  if (empty($pagerange)) {
    $pagerange = 2;
  }

  /**
   * This first part of our function is a fallback
   * for custom pagination inside a regular loop that
   * uses the global $paged and global $wp_query variables.
   * 
   * It's good because we can now override default pagination
   * in our theme, and use this function in default queries
   * and custom queries.
   */
  global $paged;
  if (empty($paged)) {
    $paged = 1;
  }
  if ($numpages == '') {
    global $wp_query;
    $numpages = $wp_query->max_num_pages;
    if(!$numpages) {
        $numpages = 1;
    }
  }

  /** 
   * We construct the pagination arguments to enter into our paginate_links
   * function. 
   */
  $pagination_args = array(
    'base'            => get_pagenum_link(1) . '%_%',
    'format'          => 'page/%#%',
    'total'           => $numpages,
    'current'         => $paged,
    'show_all'        => False,
    'end_size'        => 1,
    'mid_size'        => $pagerange,
    'prev_next'       => True,
    'prev_text'       => __('&laquo;'),
    'next_text'       => __('&raquo;'),
    'type'            => 'plain',
    'add_args'        => false,
    'add_fragment'    => ''
  );

  $paginate_links = paginate_links($pagination_args);

  if ($paginate_links) {
    echo "<nav class='custom-pagination'>";
      echo "<span class='page-numbers page-num'>Page " . $paged . " of " . $numpages . "</span> ";
      echo $paginate_links;
    echo "</nav>";
  }

}
Turbojet answered 12/2, 2017 at 17:47 Comment(3)
Following your instruction I was able to get my CPT to show and display the pagination links, but unfortunately when I click the next page /page/2 I still get a 404 error?? Any suggestions?Joappa
The only idea I have is to visit the permalinks page and re-save. This flushes them.Turbojet
I was able to get it to work Christina, I had a typo in my code. Thank you so much for your help with your post. You don't even know how much it helped me.Joappa
M
0

on the wp-include/functions.php

add those lines

function my_pagination_rewrite() {
 add_rewrite_rule('([a-z]+)/page/?([0-9]{1,})/?$', 'index.php?category_name=$matches[1]&paged=$matches[2]', 'top');
}


add_action('init', 'my_pagination_rewrite');
Mechling answered 2/4, 2019 at 14:22 Comment(2)
What will this do, and why will it fix the issue that OP is having?Sachiko
If this works, which it does not, it will be overwritten anyway on the next automatic wordpress update.Lippold
M
0

I had the same problem on my site https://chronodivers.com I have 3 similar sites all running the same theme, plugins, WP version (5.6) etc. Only this site had the problem.

All sites use PERMALINK format /%category%/%postname%/

I tried the PLUGIN ( https://wordpress.org/support/view/plugin-reviews/category-pagination-fix) didn't work for me.

I then performed these simple front end tasks

  1. Changed the Permalink format to PLAIN and saved.

  2. Flushed CACHE

  3. Changed Permalink format back to /%category%/%postname%/ and saved 40 Flushed CACHE

  4. I got a "warning" pop up from the YOAST plugin advising that due to permalink structure changes it might be necessary to rebuild index database (can't remember exact wording) and it mentioned WP CLI...

  5. I simply went to YOAST > TOOLS > Optimise SEO Data

  6. Purged cache once 5 had finished

  7. IT WORKS. I have checked ALL categories and they all work

No changing PHP files, htaccess etc. for me this time

Mohammedmohammedan answered 3/2, 2021 at 11:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.