0

I'm trying to work with paginate_links() to get a paginate structure similar to this where the bold number signifies the current page.

1 2 3

1 2 3

2 3 4

Now in theory I should be able to work with mid_size parameter which states:

mid_size
    (integer) (optional) How many numbers to either side of current page, but not including current page.
    Default: 2

My paginate_links() looks like this:

echo paginate_links( array(
        'base'          => str_replace( 9999999999, '%#%', esc_url( get_pagenum_link( 9999999999 ) ) ),
        'format'        => '?paged=%#%',
        'current'       => max( 1, get_query_var( 'paged' ) ),
        'total'         => $wp_query->max_num_pages,
        'end_size'      => 0,
        'mid_size'      => 1,
        'prev_next'     => False
) );

But for whatever reason it still shows 2 numbers on either end of my current page. If I change mid_size to 3, it shows 3 numbers on either side of the current page so I know it is picking up the parameter.

Why would it show the default of 2 numbers on either side instead of the current page even though I'm passing to only show 1 into my parameter list? How can I fix this?

1

I had a quick look at the source, and it does seem that the problem comes in at line 2267 (current version 4.1). I will however need to do some testing at some stage to make sure that this is a bug, but on face value, this is the only place I can see that this problem might occur.

There is also no filter for this specific feature that you can use to alter the current flaw

I have recently written my own pagination function to overcome a few short falls with paginate_links(), but it can be improved. I just don't have enough time to completely test some core functions and even my own functions and improve them.

I have commented the code as best as possible, so it will be easy to read and understand. Here is the function

/**
 * @author Pieter Goosen
 * @license GPLv2 
 * @link http://www.gnu.org/licenses/gpl-2.0.html
 *
 * This function returns numbered pagination links or text pagination links
 * depending what is been set
 *
 * Paginated numbered links uses get_pagenum_link() to return links to the
 * required pages
 * @uses http://wpseek.com/function/get_pagenum_link/
 *
 * The pagination links uses next_posts_link() and previous_posts_link()
 * @uses http://codex.wordpress.org/Function_Reference/next_posts_link
 * @uses http://codex.wordpress.org/Template_Tags/previous_posts_link
 *
 * @param array $args An array of key => value arguments. Defaults below 
 * - string query variable                  'query'                 => $GLOBALS['wp_query'],
 * - string Previous page text              'previous_page_text'    => __( '«' ),
 * - string Next page text                  'next_page_text'        => __( '»' ),
 * - string First page link text            'first_page_text'       => __( 'First' ),
 * - string Last page link text             'last_page_text'        => __( 'Last' ),
 * - string Older posts text                'next_link_text'        => __( 'Older Entries' ),
 * - string Newer posts text                'previous_link_text'    => __( 'Newer Entries' ),
 * - bool Whether to use links              'show_posts_links'      => false,
 * - int Amount of numbered links to show   'range'                 => 3,
 *
 * @return string $paginated_text
*/ 
function get_paginated_numbers( $args = array() ) {

    //Set defaults to use
    $defaults = array(
        'query'                 => $GLOBALS['wp_query'],
        'previous_page_text'    => __( '«' ),
        'next_page_text'        => __( '»' ),
        'first_page_text'       => __( 'First' ),
        'last_page_text'        => __( 'Last' ),
        'next_link_text'        => __( 'Older Entries' ),
        'previous_link_text'    => __( 'Newer Entries' ),
        'show_posts_links'      => false,
        'range'                 => 3,
    );

    // Merge default arguments with user set arguments
    $args = wp_parse_args( $args, $defaults );

    /**
     * Get current page if query is paginated and more than one page exists
     * The first page is set to 1
     * 
     * Static front pages is included
     *
     * @see WP_Query pagination parameter 'paged'
     * @link http://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters
     *
    */ 
    if ( get_query_var('paged') ) { 

        $current_page = get_query_var('paged'); 

    }elseif ( get_query_var('page') ) { 

        $current_page = get_query_var('page'); 

    }else{ 

        $current_page = 1; 

    }

    // Get the amount of pages from the query
    $max_pages      = (int) $args['query']->max_num_pages;

    /**
     * If $args['show_posts_links'] is set to false, numbered paginated links are returned
     * If $args['show_posts_links'] is set to true, pagination links are returned
    */
    if( false === $args['show_posts_links'] ) {

        // Don't display links if only one page exists
        if( 1 === $max_pages ) {

            $paginated_text = '';

        }else{

            /**
             * For multi-paged queries, we need to set the variable ranges which will be used to check
             * the current page against and according to that set the correct output for the paginated numbers
            */
            $mid_range      = (int) floor( $args['range'] / 2 );
            $start_range    = range( 1 , $mid_range );
            $end_range      = range( ( $max_pages - $mid_range +1 ) , $max_pages );
            $exclude        = array_merge( $start_range, $end_range );  

            /**
             * The amount of pages must now be checked against $args['range']. If the total amount of pages
             * is less than $args['range'], the numbered links must be returned as is
             *
             * If the total amount of pages is more than $args['range'], then we need to calculate the offset
             * to just return the amount of page numbers specified in $args['range']. This defaults to 5, so at any
             * given instance, there will be 5 page numbers displayed
            */
            $check_range    = ( $args['range'] > $max_pages )   ? true : false;

            if( true === $check_range ) {

                $range_numbers = range( 1, $max_pages );

            }elseif( false === $check_range ) {

                if( !in_array( $current_page, $exclude ) ) {

                    $range_numbers = range( ( $current_page - $mid_range ), ( $current_page + $mid_range ) );

                }elseif( in_array( $current_page, $start_range ) && ( $current_page - $mid_range ) <= 0 ) {

                    $range_numbers = range( 1, $args['range'] );

                }elseif(  in_array( $current_page, $end_range ) && ( $current_page + $mid_range ) >= $max_pages ) {

                    $range_numbers = range( ( $max_pages - $args['range'] +1 ), $max_pages );

                }

            }

            /**
             * The page numbers are set into an array through this foreach loop. The current page, or active page
             * gets the class 'current' assigned to it. All the other pages get the class 'inactive' assigned to it
            */
            foreach ( $range_numbers as $v ) {

                if ( $v == $current_page ) { 

                    $page_numbers[] = '<span class="current">' . $v . '</span>';

                }else{

                    $page_numbers[] = '<a href="' . get_pagenum_link( $v ) . '" class="inactive">' . $v . '</a>';

                }

            }

            /** 
            * All the texts are set here and when they should be displayed which will link back to:
             * - $previous_page The previous page from the current active page
             * - $next_page The next page from the current active page
             * - $first_page Links back to page number 1
             * - $last_page Links to the last page
            */
            $previous_page  = ( $current_page !== 1 )                       ? '<a href="' . get_pagenum_link( $current_page - 1 ) . '">' . $args['previous_page_text'] . '</a>' : '';
            $next_page      = ( $current_page !== $max_pages )              ? '<a href="' . get_pagenum_link( $current_page + 1 ) . '">' . $args['next_page_text'] . '</a>'     : '';
            $first_page     = ( !in_array( 1, $range_numbers ) )            ? '<a href="' . get_pagenum_link( 1 ) . '">' . $args['first_page_text'] . '</a>'                    : '';
            $last_page      = ( !in_array( $max_pages, $range_numbers ) )   ? '<a href="' . get_pagenum_link( $max_pages ) . '">' . $args['last_page_text'] . '</a>'            : '';

            /**
             * Text to display before the page numbers
             * This is set to the following structure:
             * - Page X of Y
            */
            $page_text      = '<span>' . sprintf( __( 'Page %s of %s' ), $current_page, $max_pages ) . '</span>';
            // Turn the array of page numbers into a string
            $numbers_string = implode( ' ', $page_numbers );

            // The final output of the function
            $paginated_text = '<div class="pagination">';
            $paginated_text .= $page_text . $first_page . $previous_page . $numbers_string . $next_page . $last_page;
            $paginated_text .= '</div>';

        }

    }elseif( true === $args['show_posts_links'] ) {

        /**
        * If $args['show_posts_links'] is set to true, only links to the previous and next pages are displayed
        * The $max_pages parameter is already set by the function to accommodate custom queries
        */
        $paginated_text = get_next_posts_link( '<div class="next-posts-link">' . $args['next_link_text'] . '</div>', $max_pages );
        $paginated_text .= get_previous_posts_link( '<div class="previous-posts-link">' . $args['previous_link_text'] . '</div>' );

    }

    // Finally return the output text from the function
    return $paginated_text;

}

/**
 * This function echo numbered pagination links or text pagination links
 * depending what is been set
 *
 * @see get_paginated_numbers() for parameters
 *
 * @return string echo get_paginated_numbers()
*/ 

function paginated_numbers( $args = array() ) {

    echo get_paginated_numbers( $args );

}

You can then call it as paginated_numbers() in your templates. Remember, you can set the parameters as arguments to suite your needs, and it works for custom queries and main query and also static front pages

Hope this help

  • I'm off to bed, been a long day. Use and abuse the function as you wish and modify as needed. Good luck – Pieter Goosen Feb 2 '15 at 18:56
  • Geez that looks hefty, thanks! I did modify [] to array() as I was getting parse errors. Also in my modified function I added an extra parameter for conditional $page_text but did not add it to yours as that was just a personal preference. This works exactly as I need it to now! – Howdy_McGee Feb 2 '15 at 19:39
  • I'm glad it worked for you. [] is only available in php 5.4, so your are on a server with an older version. Enjoy :-) – Pieter Goosen Feb 3 '15 at 4:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.