The question:
I am currently modernising an old WordPress theme (a standalone theme, not a child of any official themes). Trying to build pagination I am finding some issues creating one function that works for both archives and search. The first snippet works fine with archives (categories, loops, etc):
function pagination_bar() {
global $wp_query;
$total_pages = $wp_query->max_num_pages;
if ($total_pages > 1){
$current_page = max(1, get_query_var('paged'));
echo paginate_links(array(
'base' => get_pagenum_link(1) . '%_%',
'format' => 'page/%#%',
'current' => $current_page,
'total' => $total_pages,
'prev_text' => __('« Previous page'),
'next_text' => __('Next page »'),
));
}
}
The problem is that if I use in search results pages the links end up being domain.com/?s=QUERYpage/2
(whilst it should be domain.com/page/2/?s=query
)
So I created a custom function just for pagination in search:
function pagination_bar_search() {
global $wp_query;
$total_pages = $wp_query->max_num_pages;
if ($total_pages > 1){
$current_page = max(1, get_query_var('paged'));
echo paginate_links(array(
'base' => get_home_url() . '%_%',
'format' => '/page/%#%/',
'current' => $current_page,
'total' => $total_pages,
'prev_text' => __('« Previous page'),
'next_text' => __('Next page »'),
));
}
}
Both work correctly, but do you have any ideas for how I can combine the 2 functions and make one that works correctly for both archives and search?
I’m on the latest WordPress (5.2.3).
This is the search.php
loop function:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if ($wp_query->max_num_pages > 1)
echo 'Page ' . $paged.' of '.$wp_query->max_num_pages;
?>
...
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
...
<?php endwhile; ?>
<?php pagination_bar_search(); ?>
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
From the Codex:
To add pagination to your search results and archives, you can use
the following example:<?php global $wp_query; $big = 999999999; // need an unlikely integer echo paginate_links( array( 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), 'format' => '?paged=%#%', 'current' => max( 1, get_query_var('paged') ), 'total' => $wp_query->max_num_pages ) ); ?>
So based on that, I modified your function:
function pagination_bar( $query = null ) {
global $wp_query;
$total_pages = $query ?
$query->max_num_pages :
$wp_query->max_num_pages;
if ( $total_pages > 1 ) {
$big = 999999999; // need an unlikely integer
$current_page = max( 1, get_query_var( 'paged' ) );
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => $current_page,
'total' => $total_pages,
'prev_text' => __( '« Previous page' ),
'next_text' => __( 'Next page »' ),
) );
}
}
and it worked well, both with archives and search results.
I also added support for custom query (i.e. new WP_Query
), so that you could for example do:
$my_query = new WP_Query( array( ... ) );
pagination_bar( $my_query );
Method 2
I’m facing the same problem even after using the above approach, the problem for me isn’t coming from the WP_Query Class or the pagination.
I just figured out that the offset parameter ignores and breaks the paged parameter and the whole pagination, and the thing is I can’t let go of the offset parameter as my theme structure relies on it. Is there any solution for this matter?
Thanks
Method 3
To keep the same format rather than using a query argument, I added a check in the function to see if we are on a search page or not and modified the base and format.
/**
* Numbered pagination
*/
function so_348298_pagination_links() {
global $wp_query;
$total_pages = $wp_query->max_num_pages;
if ( $total_pages > 1 ) {
$current_page = max( 1, get_query_var( 'paged' ) );
$base = get_pagenum_link( 1 ) . '%_%';
$format = 'page/%#%';
if (is_search()) {
$base = get_home_url() . '%_%';
$format = '/page/%#%/';
}
echo '<div class="pagination-links col-12 text-center mb-5">' .
paginate_links( array(
'base' => $base,
'format' => $format,
'current' => $current_page,
'total' => $total_pages,
'type' => 'list',
) ) .
'</div>';
}
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0