Adding anchor to paginate_links + Safari anchor bug

If it can help anyone, here is the full answer with the issues that might happen when you want to add WordPress pagination with anchors to a template page.


STEP 1

Follow the example on the Codex so that the paginate_links() function applies to your custom query and not to the main query.


STEP 2

Your function should look like the code below :

global $wp_query;

$big = 999999999; // need an unlikely integer
$translated = __( 'Page', 'mytextdomain' ); // Supply translatable string

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,
    'before_page_number' => '<span class="screen-reader-text">'.$translated.' </span>'
) );

Now, several issues can happen with this code, here are a couple of solutions:

  • It’s better if you remove the 'format' => '?paged=%#%', line and let WordPress do is job with formatting permalink (it can cause issues with pretty permalink turned on) ;

  • You can have an escaping problem with the # of your anchor if you escape the get_pagenum_link()function output. In this case, just remove the esc_url() function in this part esc_url( get_pagenum_link( $big ) ) ;

  • There is an argument to add your anchor, it is called add_fragment.

Check the codex to see all the arguments you can use with this function. In the end, your code will look something like this:

$big = 999999999;
$translated = __( 'Page', 'mytextdomain' );
echo paginate_links( array(
    'base' => str_replace( $big, '%#%', get_pagenum_link( $big, false ) ),
    'current' => max( 1, get_query_var( 'paged' ) ),
    'total' => $wp_query->max_num_pages,
    'before_page_number' => '<span class="screen-reader-text">'.$translated.' </span>',
    'prev_text' => __( 'Précédent', 'epc' ), // In case you want to change the previous link text
    'next_text' => __( 'Suivant', 'epc' ), In case you want to change the next link text
    'type' => 'list', // How you want the return value to be formatted
    'add_fragment' => '#result', // Your anchor
) );

STEP 3

To finish, there is a problem with how Safari handles the redirection of pages with anchor. You might find out that the anchor is not applied when going back to first page on Safari. What you need to do (if you have pretty permalink turned on) is to filter ou the page/1 to prevent redirection. Like so:

add_filter( 'paginate_links', 'custom_pagination_redirect' );

function custom_pagination_redirect( $link ) {
    return preg_replace( '%/page/1/%', "https://wordpress.stackexchange.com/", $link );
}

And that’s it! Thanks a lot to @bonger for the precious help!

Leave a Comment