$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>Paginate Link generate additional #038; whenever my Url have multiple Query String|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

Paginate Link generate additional #038; whenever my Url have multiple Query String

matteradmin9PV0评论

My generated paginate link results will have additional #038; in the url, may I know how to get rid of it?


Blog page url : http://localhost/wordpress/blog/

I had already setup pagination with function paginate_links, when I press page [2] :

Blog page Page 2 url : http://localhost/wordpress/blog/page/2/

( everything is fine above )


However, whenever my Blog page URL have certain parameters which is for my filter/sorting purposes for WP_Query, the paginate_link result will have additional #038 params , please refer below for the URL

Blog page with Params Url : http://localhost/wordpress/blog/?filter=23&orderby=oldest

Blog page with Params Page 2 Url : http://localhost/wordpress/blog/page/2/?filter=23&orderby=oldest#038;orderby=oldest


The URL I need to achieve is http://localhost/wordpress/blog/page/2/?filter=23&orderby=oldest

below are my paginate_links functions:

global $wp_query;
$big = 99999999999;    

paginate_links([
    'base'      => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format'    => '?paged=%#%',
    'prev_text' => __('<'),
    'next_text' => __('>'),
    'current'   => max( 1, get_query_var('paged') ),
    'type'      => 'list',
    'total'     => $wp_query->max_num_pages,
    ]);

My generated paginate link results will have additional #038; in the url, may I know how to get rid of it?


Blog page url : http://localhost/wordpress/blog/

I had already setup pagination with function paginate_links, when I press page [2] :

Blog page Page 2 url : http://localhost/wordpress/blog/page/2/

( everything is fine above )


However, whenever my Blog page URL have certain parameters which is for my filter/sorting purposes for WP_Query, the paginate_link result will have additional #038 params , please refer below for the URL

Blog page with Params Url : http://localhost/wordpress/blog/?filter=23&orderby=oldest

Blog page with Params Page 2 Url : http://localhost/wordpress/blog/page/2/?filter=23&orderby=oldest#038;orderby=oldest


The URL I need to achieve is http://localhost/wordpress/blog/page/2/?filter=23&orderby=oldest

below are my paginate_links functions:

global $wp_query;
$big = 99999999999;    

paginate_links([
    'base'      => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format'    => '?paged=%#%',
    'prev_text' => __('<'),
    'next_text' => __('>'),
    'current'   => max( 1, get_query_var('paged') ),
    'type'      => 'list',
    'total'     => $wp_query->max_num_pages,
    ]);
Share Improve this question edited Dec 4, 2018 at 8:10 Krzysiek Dróżdż 25.6k9 gold badges53 silver badges74 bronze badges asked May 11, 2018 at 8:29 MavichowMavichow 1891 silver badge8 bronze badges 1
  • Have you seen this: stackoverflow/questions/27619226/… ? – Tiago Peres Commented Dec 1, 2018 at 19:28
Add a comment  | 

2 Answers 2

Reset to default 5 +50

There's no need to escape the URL twice - get_pagenum_link() by default returns an escaped URL — when the second parameter is true, esc_url() is used; else, esc_url_raw() is used:

  • With esc_url(): http://localhost/wordpress/blog/?filter=23&orderby=oldest

  • With esc_url_raw(): http://localhost/wordpress/blog/?filter=23&orderby=oldest

And the problem occurs when the base contains ?, or a query string, and that the URL is escaped (e.g. using esc_url()).

Because esc_url() converts & (ampersand) to its HTML entity, which is &, and when the base contains a query string, paginate_links() will parse the base value/URL, and when the & is escaped, anything after each & and the nearest = is treated as a query string name/key, and added to the base's query string:

http://localhost/wordpress/blog/?filter=23&orderby=oldest#038;orderby=oldest

In the above example, the URL is like that because paginate_links() (or more precisely, wp_parse_str() used in paginate_links()) interpreted #038;orderby as the key of oldest; i.e. #038;orderby=oldest — it should be &orderby=oldest where the key is orderby.

(But of course, the browser sees anything after the # as a URL fragment. And if you follow the link, on the next page, $_GET will not have an entry for #038;orderby; i.e. $_GET['#038;orderby'] doesn't exist.)

So here are several ways to fix/avoid the problem:

  1. Use html_entity_decode() just as WordPress does via paginate_links():

    'base' => str_replace( $big, '%#%', html_entity_decode( get_pagenum_link( $big ) ) )
    
  2. When you call get_pagenum_link(), set the second parameter set to false:

    'base' => str_replace( $big, '%#%', get_pagenum_link( $big, false ) )
    
  3. Use str_replace() to replace the & with &:

    'base' => str_replace( [ $big, '&' ], [ '%#%', '&' ], get_pagenum_link( $big ) )
    

Don't worry about not escaping the base because paginate_links() actually escapes all the links/URLs in the returned result.

Friendly Warning: Some of the links in this answer point you to a huge HTML file / web page..

It looks like this is a known issue with paginate_links function.

Here's a quick workaround, which will work well, if only there are no ampersands in your query params values:

<?php
    global $wp_query;
    $big = 99999999999;

    echo paginate_links(array(
        'base'      => str_replace( array($big, '#038;'), array('%#%', ''), esc_url( get_pagenum_link( $big ) ) ),
        'format'    => '?paged=%#%',
        'prev_text' => __('&lt;'),
        'next_text' => __('&gt;'),
        'current'   => max( 1, get_query_var('paged') ),
        'type'      => 'list',
        'total'     => $wp_query->max_num_pages,
    ));
?>
Post a comment

comment list (0)

  1. No comments so far