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
2 Answers
There are some things that should be changed in your code:
- Please no not use
$_SESSION
stuff. So do not add session_start anywhere. You can pass the current state via the query string, usingmethod="get"
in your form. - 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 - When you have to access superglobals array, instead of accessing directly is recomned to use
filter_input
- in the
overview-search-input.php
file, last line is$query = search_v1($_SESSION['period']);
that is completely useless - 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
andsingle.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);
}