Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>";
  }

}
like image 308
Roman Verner Avatar asked Dec 03 '22 13:12

Roman Verner


1 Answers

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>";
  }

}
like image 82
Christina Avatar answered Dec 28 '22 17:12

Christina