3

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.

2
  • 1
    What is the code of aws_search_byozan()? Could it be overwriting the paged query var? If you get_query_var( 'paged' ) before calling that, what is the value?
    – J.D.
    Aug 12, 2017 at 13:14
  • @J.D. I updated my question based on your response, and removed aws_search_byozan() from code. Problem still exists.
    – HOY
    Aug 12, 2017 at 14:54

3 Answers 3

1
+50

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 ) );
5
  • 1
    Note that you could just use wp_parse_str() instead of splitting the $query_string manually. I've updated the codex example to do this, as it is much simpler.
    – J.D.
    Aug 12, 2017 at 15:25
  • 1
    Not sure whether I should leave my answer as-is because it's the version OP saw originally or update it to match the updated Codex. Thoughts?
    – Chris Cox
    Aug 12, 2017 at 15:39
  • 1
    I think it is good to improve an answer, although if the change is substantial you might want to let the OP know. In this case though, I wouldn't think that is necessary, since the result should be the same as before; it doesn't actually change the code's behavior. Of course, if you don't update the answer people will still see my comment. But if you do update it I can remove my comments and reduce clutter. :-)
    – J.D.
    Aug 12, 2017 at 19:47
  • hi chris, Its okey for me if you update your answer, I can find the previous version from your edited section. I am currently analysing your solution, not tested yet.
    – HOY
    Aug 12, 2017 at 22:00
  • @ChrisCox when I implemented your system, it did not change anything and I debugged and realized something. Paged was even not inside the $query_string, which made me think that my URL rediraction has some problems. So I have checked my add_rewrite_rule, and saw that I did not send paged as a paramter. So I have edited it and everything fixed, and it works even without codes above with it's inital state. Your answer here does not my exact answer, but you showed me the way by $query_string which I was not aware of before, I'll give you the bounty. @J.D. thank you for your help too.
    – HOY
    Aug 14, 2017 at 1:00
1

for this problem you first use a pagination function like this :

 function cupagenavi() {
global $wp_query, $wp_rewrite;
$pages = '';
$max = $wp_query->max_num_pages;
if (!$current = get_query_var('paged')) $current = 1;
$a['base'] = ($wp_rewrite->using_permalinks()) ? user_trailingslashit( trailingslashit( remove_query_arg( 'page', get_pagenum_link( 1 ) ) ) . '?page=%#%', 'page' ) : @add_query_arg('page','%#%');
if( !empty($wp_query->query_vars['s']) ) $a['add_args'] = array( 's' => get_query_var( 's' ) );
$a['total'] = $max;
$a['current'] = $current;
$total = 1;
$a['mid_size'] = 4;
$a['end_size'] = 4;
$a['prev_text'] = 'Previous Page';
$a['next_text'] = 'Next Page';
if ($max > 1) echo '';
echo $pages . paginate_links($a);
if ($max > 1) echo '';
}

for using this function use this code

if (function_exists('cupagenavi')) cupagenavi();

and then in your query post use :

$paged = $_GET['page'];
$args = array(
    'post_type' => 'product',
    'posts_per_page' => '2',
    'paged' => $paged,
);
query_posts($args);
1

it is not fully clear which 'paged' variable you refer, because you have it in different places.

actually, instead of $wp_query->get.. you should try $loop or $GLOBALS['wp_query']

//sent from mobile,sorry for grammar

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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