paginate_links WP function

So the purpose of the function is not that hard: generate a set of URLs of a total size with current page and some pretty parts.

The issue is that the way URL is configured is quite… original and documentation doesn’t quite describe what happens accurately.

The documentation implies that these are default base and format arguments:

echo '<pre>', esc_html( paginate_links( [
    'base'    => '%_%',
    'format'  => '?page=%#%',
    'current' => 1,
    'total'   => 3,
    'type'    => 'plain',
] ) ), '</pre>';

<span class="page-numbers current">1</span>
<a class="page-numbers" href="https://wordpress.stackexchange.com/questions/232283/?page=2">2</a>
<a class="page-numbers" href="?page=3">3</a>
<a class="next page-numbers" href="https://wordpress.stackexchange.com/questions/232283/?page=2">Next »</a>

That’s not actually true. The default base and format are generated dynamically, depending on site’s configuration. For my dev site they would be like this:

echo '<pre>', esc_html( paginate_links( [
    'base'    => 'http://dev.rarst.net/%_%',
    'format'  => 'page/%#%/',
    'current' => 1,
    'total'   => 3,
    'type'    => 'plain',
] ) ), '</pre>';

<span class="page-numbers current">1</span>
<a class="page-numbers" href="http://dev.rarst.net/page/2/">2</a>
<a class="page-numbers" href="http://dev.rarst.net/page/3/">3</a>
<a class="next page-numbers" href="http://dev.rarst.net/page/2/">Next »</a>

So what happens there? Two things:

  1. %#% in format is replaced with current page number.
  2. Then %_% in base is replaced with format result.

So for page 2:

  1. 2 + page/%#%/ = page/2/
  2. page/2/ + http://dev.rarst.net/%_% = http://dev.rarst.net/page/2/

Rest of the arguments deals with “pretty” stuff like splitting into segments and such (so that you don’t actually show 1000 links for 1000 pages).

So I guess the summary is: the function is very flexible and allows to build wildly different pagination schemes. But you really need to have specific goal in mind to build base and format correctly.

There are some higher level wrappers, that were added later and are more specific to the tasks, for example the_posts_pagination().