Custom Search Page Pagination Not Working

My Seach Page URLs:

https://www.example.com/search/keyword/page/2/

Here my custom search page:

<?php 

    if($_GET['search_text'] && !empty($_GET['search_text']))
    {
        $text = $_GET['search_text'];
    }
    else
    {
        $text = urldecode( get_query_var('search_text') ) ;            
    }

?>

<div id="primary" class="content-area">
    <main id="main" class="site-main" role="main">            
        <div class="searchpage-container">
            <div class="searchpage-filter-container">
                <span>Arama Sonuçları:</span>
            </div>                
            <div class="product-container">
                <?php
                    $my_products = array( 2085, 4094, 2900, 4072, 131 );

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

                    $args = array(
                        'post_type' => 'product',
                        'posts_per_page' => 2,
                        'paged' => $paged,
                        'post__in' => $my_products

                    );
                    $loop = new WP_Query( $args );

                    if ( $loop->have_posts() ) {
                        while ( $loop->have_posts() ) : $loop->the_post();
                            wc_get_template_part( 'content', 'product' );
                        endwhile;

                        $total_pages = $loop->max_num_pages;

                        if ($total_pages > 1){

                            /* $current_page = max(1, get_query_var('paged')); */
                            $wp_query->query_vars['paged'] > 1 ? $current_page = $wp_query->query_vars['paged'] : $current_page = 1;   
                            echo $wp_query->query_vars['paged'];

                            echo paginate_links(array(
                                'base' => get_pagenum_link(1) . '%_%',
                                'format' => '/page/%#%',
                                'current' => $current_page,
                                'total' => $total_pages,
                                'prev_text'    => __('« prev'),
                                'next_text'    => __('next »'),
                            ));
                        }
                    } 
                    wp_reset_postdata();                    

                ?>  
            </div>            
        </div>


    </main><!-- #main -->
</div><!-- #primary -->

My pagination links are created fine, but I always see the page No 1 because somehow query_vars['paged'] is emtpy.

I have seen Preserving Search Page Results and Pagination section on this page , but couldn’t figure it out how to use it, but I don’t think this is really needed in my case.

EDIT 1 (Response to comment from J.D.):

That function you mentioned only returns an array of product IDs, to simplify my code, I removed my function add a static array instead.

3 Answers
3

You’re running into a conflict between your replacement query and the default search query that’s running behind the scenes.

Instead of running a new WP_Query, try modifying the default query by hooking to pre_get_posts:

function wpse276396_search_filter($query) {
  if ( !is_admin() && $query->is_main_query() ) {
    if ($query->is_search) {
      $text = urldecode( get_query_var('search_text') );
      $my_products = aws_search_byozan($text);
      $query->set('post_type', 'product');
      $query->set('posts_per_page', 2);
      $query->set('post__in', $my_products);
    }
  }
}

add_action('pre_get_posts','wpse276396_search_filter');

Then you’d output the default Loop in your template instead of your custom WP_Query Loop.

This has the advantage of not hitting the database once for the default query then disregarding the results and using your custom query to render the page instead, plus the paged and posts_per_page arguments are consistent with what WP expects.

Edit: I somehow managed to miss that this is in a page template. That’s enough WPSE for me for today, but I’ll update my answer to reflect that rather than modifying the default search query (which is still a better option unless you need your custom search to coexist with the built-in search form).

In this case what’s happening is WP is expecting the paged and posts_per_page arguments to apply to the main query which fetched your search Page, which means the instructions on the Codex page you linked absolutely do apply.

$my_products = aws_search_byozan($text);
global $query_string;

$query_args = explode("&", $query_string);
$search_query = array();

if( strlen($query_string) > 0 ) {
    foreach($query_args as $key => $string) {
        $query_split = explode("=", $string);
        $search_query[$query_split[0]] = urldecode($query_split[1]);
    } // foreach
} //if

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

$args = array(
    'post_type' => 'product',
    'posts_per_page' => 2,
    'paged' => $paged,
    'post__in' => $my_products

);
$loop = new WP_Query( array_merge($search_query, $args ) );

Leave a Comment