2

I have been using the same pagination query for the majority of the websites i have created. This time it is not working for some reason I have used the pagination trouble shooting links Here but nothing seems to be working. I have attached my code below.

This time i am querying the post in a table so i think that must have something to do with it but i have queried it without a table and is still not working. Please see my code below.

New query

<?php
$args = array(
    'post_type' => 'custom_post_type',
    'posts_per_page' => 5,
    'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
);
query_posts($args);
?>

The table with my table data from my custom meta fields.

<table>
    <thead >
        <tr>

            <th>header</th>
            <th>header</th>
            <th>header</th>
            <th>header</th>

        </tr>
    </thead>
    <tbody>

        <?php  while (have_posts()) : the_post();?>
            <tr>

                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    

            </tr>
        <?php
        endwhile;
        ?>

    </tbody>
</table>

My pagination links

<?php
global $wp_query;

$big = 999999999; // need an unlikely integer

echo paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format' => '?paged=%#%',
    'prev_text'          => __(' Previous'),
    'next_text'          => __('Next '),
    'current' => max( 1, get_query_var('paged') ),
    'total' => $wp_query->max_num_pages
) );
?>

When I say its not working i mean that the pagination links are displayed the appropriate number of pages. but when i press on page two it isnt changing pages. the permalinks are right its says domain/page/2 but the page is the same as page one. This is on a template page i created for home-page.php I appreciate the suggestions.

5
  • describe what you mean by not working, what happens? what type of page is this on?
    – Milo
    Commented Apr 27, 2015 at 22:49
  • Hello @Milo Thank you for your response, when I say its not working i mean that the pagination links are displayed the appropriate number of pages. but when i press on page two it isnt changing pages. the permalinks are right its says domain/page/2 but the page is the same as page one. This is on a template page i created for home-page.php I appreciate the help.
    – steamfunk
    Commented Apr 27, 2015 at 23:49
  • Do not use query_posts, it breaks pagination and the main query Commented Apr 28, 2015 at 4:59
  • Also, please note, your comment should be an edit to your question. Many others skip and ignore comments, and they will skip and ignore your question as doesn't work also don't make much sense to them Commented Apr 28, 2015 at 5:55
  • @PieterGoosen thank you once again i will keep that in mind!
    – steamfunk
    Commented Apr 28, 2015 at 6:25

2 Answers 2

3

As I already stated in comments, you should never use query_posts, only use query_posts if you are intended to break your page functionalities. Add query_posts to the very top of your EVIL LIST.

query_posts breaks the main query object, the very object that your pagination function relies on. Your pagination function relies on the $max_num_pages property from the main query. This is just one of the many things that query_posts break.

To solve your issue, make use of WP_Query as it seems that you are using a custom page template here. Just one note here, if home-page.php is a static front page, which I suspect from the template name, then

'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),

should be

'paged' => ( get_query_var('page') ? get_query_var('page') : 1),

as static front pages uses page and not paged

You can try something like this: (Very important, this is untested and copied and pasted from OP, and always remember to reset postdata once you are done with your custom query)

<?php
$args = array(
    'post_type' => 'custom_post_type',
    'posts_per_page' => 5,
    'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
);
$query = new WP_Query($args);
?>
<table>
    <thead >
        <tr>

            <th>header</th>
            <th>header</th>
            <th>header</th>
            <th>header</th>

        </tr>
    </thead>
    <tbody>

        <?php  while ($query->have_posts()) : $query->the_post();?>
            <tr>

                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    

            </tr>
        <?php
        endwhile;
        wp_reset_postdata();
        ?>

    </tbody>
</table>

You then just need to update your pagination function with the $max_num_pages property rom your custom query

<?php
$big = 999999999; // need an unlikely integer

echo paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format' => '?paged=%#%',
    'prev_text'          => __(' Previous'),
    'next_text'          => __('Next '),
    'current' => max( 1, get_query_var('paged') ),
    'total' => $query->max_num_pages
) );
?>
2
  • Amazing thank you i really appreciate it. I did not know of that before.
    – steamfunk
    Commented Apr 28, 2015 at 21:39
  • did this change recently? As of 2018 "paged" was working but it stopped working recently (2020). Changed to "page" and is now working
    – thebigtine
    Commented Feb 22, 2021 at 16:30
1

I was using a custom query and needed to paginate my query results. Since the original paginate_links() function is heavily tied to the global $wp_query and $wp_rewrite contexts, I have adapted it to be completely independent. usage:

function myPaginateLinks( WP_Query $wp_query, $args = '' ) {
    global $wp_rewrite;

    // Setting up default values based on the current URL.
    $pagenum_link = html_entity_decode( get_pagenum_link() );
    $url_parts    = explode( '?', $pagenum_link );

    // Get max pages and current page out of the current query, if available.
    $total   = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1;
    $current = !empty($_GET['pg']) ? absint($_GET['pg']) : 1;

    // Append the format placeholder to the base URL.
    $pagenum_link = trailingslashit( $url_parts[0] ) . '%_%';

    // URL base depends on permalink settings.
    $format  = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
    $format .= '?pg=%#%';

    $defaults = array(
        'base'               => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below).
        'format'             => $format, // ?page=%#% : %#% is replaced by the page number.
        'total'              => $total,
        'current'            => $current,
        'aria_current'       => 'page',
        'show_all'           => false,
        'prev_next'          => true,
        'prev_text'          => __( '&laquo; Previous' ),
        'next_text'          => __( 'Next &raquo;' ),
        'end_size'           => 1,
        'mid_size'           => 2,
        'type'               => 'plain',
        'add_args'           => array(), // Array of query args to add.
        'add_fragment'       => '',
        'before_page_number' => '',
        'after_page_number'  => '',
    );

    $args = wp_parse_args( $args, $defaults );

    if ( ! is_array( $args['add_args'] ) ) {
        $args['add_args'] = array();
    }

    // Merge additional query vars found in the original URL into 'add_args' array.
    if ( isset( $url_parts[1] ) ) {
        // Find the format argument.
        $format       = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) );
        $format_query = isset( $format[1] ) ? $format[1] : '';
        wp_parse_str( $format_query, $format_args );

        // Find the query args of the requested URL.
        wp_parse_str( $url_parts[1], $url_query_args );

        // Remove the format argument from the array of query arguments, to avoid overwriting custom format.
        foreach ( $format_args as $format_arg => $format_arg_value ) {
            unset( $url_query_args[ $format_arg ] );
        }

        $args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $url_query_args ) );
    }

    // Who knows what else people pass in $args.
    $total = (int) $args['total'];
    if ( $total < 2 ) {
        return;
    }
    $current  = (int) $args['current'];
    $end_size = (int) $args['end_size']; // Out of bounds? Make it the default.
    if ( $end_size < 1 ) {
        $end_size = 1;
    }
    $mid_size = (int) $args['mid_size'];
    if ( $mid_size < 0 ) {
        $mid_size = 2;
    }

    $add_args   = $args['add_args'];
    $r          = '';
    $page_links = array();
    $dots       = false;

    if ( $args['prev_next'] && $current && 1 < $current ) :
        $link = str_replace( '%_%', 2 == $current ? '' : $args['format'], $args['base'] );
        $link = str_replace( '%#%', $current - 1, $link );
        if ( $add_args ) {
            $link = add_query_arg( $add_args, $link );
        }
        $link .= $args['add_fragment'];

        $page_links[] = sprintf(
            '<a class="prev page-numbers" href="%s">%s</a>',
            /**
             * Filters the paginated links for the given archive pages.
             *
             * @since 3.0.0
             *
             * @param string $link The paginated link URL.
             */
            esc_url( apply_filters( 'paginate_links', $link ) ),
            $args['prev_text']
        );
    endif;

    for ( $n = 1; $n <= $total; $n++ ) :
        if ( $n == $current ) :
            $page_links[] = sprintf(
                '<span aria-current="%s" class="page-numbers current">%s</span>',
                esc_attr( $args['aria_current'] ),
                $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number']
            );

            $dots = true;
        else :
            if ( $args['show_all'] || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
                $link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
                $link = str_replace( '%#%', $n, $link );
                if ( $add_args ) {
                    $link = add_query_arg( $add_args, $link );
                }
                $link .= $args['add_fragment'];

                $page_links[] = sprintf(
                    '<a class="page-numbers" href="%s">%s</a>',
                    /** This filter is documented in wp-includes/general-template.php */
                    esc_url( apply_filters( 'paginate_links', $link ) ),
                    $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number']
                );

                $dots = true;
            elseif ( $dots && ! $args['show_all'] ) :
                $page_links[] = '<span class="page-numbers dots">' . __( '&hellip;' ) . '</span>';

                $dots = false;
            endif;
        endif;
    endfor;

    if ( $args['prev_next'] && $current && $current < $total ) :
        $link = str_replace( '%_%', $args['format'], $args['base'] );
        $link = str_replace( '%#%', $current + 1, $link );
        if ( $add_args ) {
            $link = add_query_arg( $add_args, $link );
        }
        $link .= $args['add_fragment'];

        $page_links[] = sprintf(
            '<a class="next page-numbers" href="%s">%s</a>',
            /** This filter is documented in wp-includes/general-template.php */
            esc_url( apply_filters( 'paginate_links', $link ) ),
            $args['next_text']
        );
    endif;

    switch ( $args['type'] ) {
        case 'array':
            return $page_links;

        case 'list':
            $r .= "<ul class='page-numbers'>\n\t<li>";
            $r .= implode( "</li>\n\t<li>", $page_links );
            $r .= "</li>\n</ul>\n";
            break;

        default:
            $r = implode( "\n", $page_links );
            break;
    }

    /**
     * Filters the HTML output of paginated links for archives.
     *
     * @since 5.7.0
     *
     * @param string $r    HTML output.
     * @param array  $args An array of arguments. See paginate_links()
     *                     for information on accepted arguments.
     */
    $r = apply_filters( 'paginate_links_output', $r, $args );

    return $r;
}

Usage example:

$myQuery = new WP_Query();

$cars = $myQuery->query([
    'post_type' => 'cars',
    'paged' => !empty($_GET['pg']) ? absint($_GET['pg']) : 1,
]);

foreach ($cars as $car) {
    echo $car->post_title;
}

echo myPaginateLinks($myQuery);

Which produces the exact same result as paginate_links, but without any ties to the global query or rewrite rules:

wordpress pagination custom query custom post type cpt

Notice that I'm using $_GET['pg'] instead of ?paged for the pagination, as I didn't want any "rewrite magic" getting into the way of the pagination.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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