The question:
I’m using the following code to generate some pagination:
$wp_query = new WP_Query();
$wp_query->query('posts_per_page=5'.'&paged='.$paged);
$big = 999999999;
echo '<div class="pagination">';
echo paginate_links(array( 'base' => '%_%',
'format' => str_replace($big, '%#%', esc_url(get_pagenum_link( $big ))),
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'end_size' =>4,
'type' => 'list'));
echo '</div>';
Its generating my links correctly on the first page, but if I go to any other page everything is still correct except the link for page 1 is always the url of whatever page I am on. Seems like I’m missing somthing simple, anyone know a fix?
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
Short answer:
Try
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
Long answer:
I took a look at the paginate_links()
source code (v3.5.1) and there is this line (#)
$link = str_replace('%_%', 1 == $n ? '' : $format, $base);
that is giving you the empty first page link.
With your setup you have $base = "%_%"
and $format = "http://example.com/page/%#%/"
so this becomes:
$link = str_replace('%_%', 1 == $n ? '' : "http://example.com/page/%#%/", "%_%");
where we have two cases:
n=1: $link = str_replace('%_%', '', "%_%");
n>1: $link = str_replace('%_%', "http://example.com/page/%#%/", "%_%");
and after the replacement:
n=1: $link = '';
n>1: $link = "http://example.com/page/%#%/";
Here is an example of the output from paginate_links()
:
<ul class='page-numbers'>
<li><a class="prev page-numbers" href="http://example.com/page/2/" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">« Previous</a></li>
<li><a class='page-numbers' href=''>1</a></li>
<li><a class='page-numbers' href='http://example.com/page/2/'>2</a></li>
<li><span class='page-numbers current'>3</span></li>
<li><a class='page-numbers' href='http://example.com/page/4/'>4</a></li>
<li><a class='page-numbers' href='http://example.com/page/5/'>5</a></li>
<li><a class='page-numbers' href='http://example.com/page/6/'>6</a></li>
<li><a class="next page-numbers" href="http://example.com/page/4/" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Next »</a></li>
</ul>
If you use instead (#):
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
then you get:
$link = str_replace('%_%', 1 == $n ? '' : "?paged=%#%", "http://example.com/page/%#%");
Since no replacement will take place
$link = "http://example.com/page/%#%";
in both cases (n=1 and n>1) and you have a non empty first page link with the output of paginate_links()
:
<ul class='page-numbers'>
<li><a class="prev page-numbers" href="http://example.com/page/2/" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">« Previous</a></li>
<li><a class='page-numbers' href='http://example.com/page/1/'>1</a></li>
<li><a class='page-numbers' href='http://example.com/page/2/'>2</a></li>
<li><span class='page-numbers current'>3</span></li>
<li><a class='page-numbers' href='http://example.com/page/4/'>4</a></li>
<li><a class='page-numbers' href='http://example.com/page/5/'>5</a></li>
<li><a class='page-numbers' href='http://example.com/page/6/'>6</a></li>
<li><a class="next page-numbers" href="http://example.com/page/4/" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Next »</a></li>
</ul>
To have a non empty first page link it looks like $format
can be any string as long as $base
doesn’t include the string "%_%"
, i.e. these should work fine:
'format' => '?paged=%#%',
'format' => 'page/%#%',
'format' => 'asdfasdfasdfasdfasdf',
If you don’t use permalinks, then the example in (#) will also give you non empty first page link since
$link = str_replace('%_%', 1 == $n ? '' : "?paged=%#%", "http://example.com/?paged=%#%");
with replacements.
Method 2
Thanks birgire for help. I’m sharing the result of my paginate_links() which are working with custom taxonomy pages exactly as I need.
Hope this will help someone to fix it as quick as possible.
So here it is:
if (empty($pagerange)) {
$pagerange = 2;
}
global $paged;
if (empty($paged)) {
$paged = 1;
}
if ($numpages == '') {
global $wp_query;
$numpages = $wp_query->max_num_pages;
if(!$numpages) {
$numpages = 1;
}
}
$pagination_args = array(
'base' => str_replace('%_%', 1 == $paged ? '' : "?page=%#%", "?page=%#%"),
'format' => '?page=%#%',
'total' => $numpages,
'current' => $paged,
'show_all' => False,
'end_size' => 1,
'mid_size' => $pagerange,
'prev_next' => True,
'prev_text' => __('<i class="fa fa-angle-left"></i>'),
'next_text' => __('<i class="fa fa-angle-right"></i>'),
'type' => 'list',
'add_args' => false,
'add_fragment' => ''
);
$paginate_links = paginate_links($pagination_args);
if ($paginate_links) {
echo "<nav class='custom-pagination'><ul>";
echo $paginate_links;
echo "</ul></nav>";
}
Method 3
I stumbled on a same problem and found out that I can replace:
'current' => max( 1, get_query_var('paged') ),
with:
'current' => max( 1, get_query_var('page') ),
So just renamed ‘paged’ >’page’ in query var and it works.
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