Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

There is a question very similar to mine, which can be found here. The difference with my question is: my search form is on several pages (page.php and single.php) and I don't use wp-pagenavi. I've tried the suggested solutions posted there but they didn't work.

What is working

  • The query displays the right results
  • The query displays the right results after form submission
  • Pagination shows with the correct links (ie example.com/overview/?paged=2 and example.com/city/boston/?paged=2)
  • Pagination with the same settings works on search.php

What is not working: if I submit the form and click on any page but page 1 the URL does become example.com/overview/?paged=2 or example.com/city/boston/?paged=2 but no results are displayed.

Updated after the accepted answer: Please read the notes in the code to see how the problem was solved.

--- Below here the setup of my code

On page.php

if(is_page('overview')) {
    get_template_part('templates/overview', 'main');
}

On single.php (include the same file)

if(is_singular('cities')) {
    get_template_part('templates/overview', 'main');
}

On overview-main.php

include_once 'overview-search-input.php'; 
include_once 'overview-sidebar.php';

On overview-search-input.php (changed after UPDATE 3, original code below here)

   if(!empty($_GET['period'])) {
        $period = $_GET['period'];
   }
   else {
        $period = 'upcoming'; // Set to upcoming if nothing is selected
   }

   $query = search_v1($period, $paged); // Passing the $paged parameter in the query

   $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // The $paged parameter

On overview-sidebar.php

<form action="<?php echo get_permalink(); ?>" method="get"> 
<select name="period" placeholder="Select">
  <option value=""></option>
  <option value="all"></option>
  <option value="upcoming"></option>
</select>
</form>

in the function search_v1:

    $args = array(
        'post_type'         => 'events',
        'post_status'       => 'publish',
        'posts_per_page'    => 20,
        'paged'             => $paged, // This was passed into the function
        'meta_query'        => array($meta_query), // This is generated based on the $period input and it's working (tested)
        'meta_key'          => 'date_from',
        'orderby'           => 'meta_value',
        'order'             => 'ASC',
    );

    return new WP_Query($args);

Then on overview-main.php

   if($query->have_posts()): while ($query->have_posts()): $query->the_post();
      // Do stuff
    endwhile;

    create_pagination($query);

    wp_reset_postdata();
    endif;

And in the function create_pagination:

$query->query_vars['paged'] > 1 ? $current = $query->query_vars['paged'] : $current = 1;

$args = array(
    'base' => @add_query_arg('paged','%#%'),
    'format' => '?paged=%#%',
    'total' => $query->max_num_pages,
    'current' => $current,
    'show_all' => false,
    'end_size' => 1,
    'mid_size' => 2,
    'prev_next' => true,
    'prev_text' => '<i class="icon-chevron-left"></i>',
    'next_text' => '<i class="icon-chevron-right"></i>',
    'type' => 'list'
);

return paginate_links($args);

The problem was: Since both pagination functions work and display the correct pagination links I assume that's not the problem. I think it lies in the custom query (since this pagination works on search.php when the results are generated once and not altered by form input).

The problem was solved: by using the 'paged' parameter and passing it into the query

share|improve this question
    
If you're sending POST data to a page to manipulate the query, that data isn't persisted across subsequent page loads, because you're not POSTing that data again. –  Milo Nov 8 '13 at 15:34
    
That explains. Can you point me in the right direction of how to post the data again? –  eskimo Nov 8 '13 at 16:56
1  
you don't need sessions. change your form to submit via get instead of post, then you can just append any existing form get vars onto your pagination links. –  Milo Nov 15 '13 at 22:24
    
This question has been solved - reward the bounty to @G.M. please! :) –  Eric Holmes Nov 21 '13 at 14:27
    
Thanks Eric. This was my first time putting a bounty on a question and I thought it would be granted by accepting the answer. I've rewarded it now. –  eskimo Nov 21 '13 at 18:20
add comment

2 Answers

up vote 2 down vote accepted
+50

There are some things that should be changed in your code:

  1. Please no not use $_SESSION stuff. So do not add session_start anywhere. You can pass the current state via the query string, using method="get" in your form.
  2. For a better flow, you can pass the current page to search_v1 function as argument, in this way you are sure will be not errors
  3. When you have to access superglobals array, instead of accessing directly is recomned to use filter_input
  4. in the overview-search-input.php file, last line is $query = search_v1($_SESSION['period']); that is completely useless
  5. I think is useful in the form select the period option of the current showed posts, e.g. when you are viewing posts for period 'upcoming', in the form should be selected the option 'upcoming'.

Applying this changes:

  • page.php and single.php and stay unchanged.
  • remove session_start(); from where you have added

Then

overview-search-input.php

<?php
$period = filter_input(INPUT_GET, 'period', FILTER_SANITIZE_STRING);
$paged = get_query_var('paged');
if ( empty($period ) ) $period  = 'upcoming';
if ( empty($paged) ) $paged = 1;

overview-sidebar.php

<form action="<?php echo get_permalink(); ?>" method="get">
<select name="period" placeholder="Select">
  <option <?php selected('', $period) ?>></option>
  <option <?php selected('all', $period) ?>>all</option>
  <option <?php selected('upcoming', $period) ?>>upcoming</option>
</select>
</form>

overview-main.php

include_once 'overview-search-input.php';
include_once 'overview-sidebar.php';

$query = search_v1( $period, $paged );

if( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();
  // Do stuff
endwhile;

echo create_pagination( $query, $period );

wp_reset_postdata();
endif;

Finally the 2 functions, search_v1 and create_pagination:

function search_v1( $period = 'upcoming', $paged = 1 ) {
  if ( empty($paged) ) $paged = 1;
  $meta_query = array(
    // create your meta query here
  );
  $args = array(
    'post_type'         => 'events',
    'post_status'       => 'publish',
    'posts_per_page'    => 20,
    'paged'             => $paged,
    'meta_query'        => array($meta_query),
    'meta_key'          => 'date_from',
    'orderby'           => 'meta_value',
    'order'             => 'ASC',
  );
  return new WP_Query( $args );
}


function create_pagination( $query, $period = 'upcoming' ) {
  $current = isset($query->query_vars['paged']) ? $query->query_vars['paged'] : 1;
  $args = array(
    'base' => get_permalink() . '%_%',
    'format' => '?paged=%#%&period=' . $period,
    'total' => $query->max_num_pages,
    'current' => ($current > 0) ? $current : 1,
    'show_all' => false,
    'end_size' => 1,
    'mid_size' => 2,
    'prev_next' => true,
    'prev_text' => '<i class="icon-chevron-left"></i>',
    'next_text' => '<i class="icon-chevron-right"></i>',
    'type' => 'list'
  );
  return paginate_links($args);
}
share|improve this answer
    
Thanks! My full code is way more complex and I did some alterations on yours, but this was definitely the answer that made it work. I'll update my question to show the working code. But it leaves me with one point of confusion; what's the deal with 'paged' vs 'page' in the query arguments? Because @Subharanjan suggested 'page' is used for custom queries, but I'm now using 'paged' and everyting works fine. –  eskimo Nov 16 '13 at 13:33
add comment

Instead of this line

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

Can you use this and check.

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

Also this

$query->query_vars['paged'] > 1 ? $current = $query->query_vars['paged'] : $current = 1;

to

$query->query_vars['page'] > 1 ? $current = $query->query_vars['page'] : $current = 1;

Note: As you are using custom page templates, "paged" doesn't work there.

share|improve this answer
    
If I do that I get the error Notice: Undefined index: page. If I change the 'paged' parameter to 'page' in the $args of $query the problem is the same as described. –  eskimo Nov 15 '13 at 21:00
    
PS I've also changed paged to page in @add_query_arg and paged to page in '?paged=%#%` of to no avail. –  eskimo Nov 15 '13 at 21:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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