Site icon Hip-Hop Website Design and Development

paginate_links appearing on page but it doesn’t actually paginate – pagination on a static page with a dynamic `post_type` argument on a static page

I’m doing a custom post loop like this;

<?php
            $args = array(
                'post_type' => $resourcesPostTypes,
                'post_status' => array('publish'),
                'orderby' => 'date',
                'order' => 'DESC',
                'post__not_in'   => array(15552, 15554, 15555),
                'posts_per_page' => $posts_to_display
            );

            $query = new WP_Query($args);
            $resourceCount = 0;

            if ($query->have_posts()) {
                while ($query->have_posts()) {
                // .... rest of everything here

And I needed to add pagination. After some extensive research I found this:

<?php 
                    echo paginate_links( array(
                        'base'         => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
                        'total'        => $query->max_num_pages,
                        'current'      => max( 1, get_query_var( 'paged' ) ),
                        'format'       => '?paged=%#%',
                        'show_all'     => false,
                        'type'         => 'plain',
                        'end_size'     => 2,
                        'mid_size'     => 1,
                        'prev_next'    => true,
                        'prev_text'    => sprintf( '<i></i> %1$s', __( 'Newer Posts', 'text-domain' ) ),
                        'next_text'    => sprintf( '%1$s <i></i>', __( 'Older Posts', 'text-domain' ) ),
                        'add_args'     => false,
                        'add_fragment' => '',
                    ) );
                ?>

Which is rendering, so in it’s full context we have:

<section class="resources-blocks">
    <div class="grid-container">
        <div class="grid-x grid-margin-x align-center" id="container">
            <?php
            $current_url =  "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

            $active_query_param = parse_url($current_url, PHP_URL_QUERY);

            if($active_query_param) {
                $resourcesPostTypes = $active_query_param;
            }
            ?>
            <?php
            $args = array(
                'post_type' => $resourcesPostTypes,
                'post_status' => array('publish'),
                'orderby' => 'date',
                'order' => 'DESC',
                'post__not_in'   => array(15552, 15554, 15555),
                'posts_per_page' => $posts_to_display
            );

            $query = new WP_Query($args);
            $resourceCount = 0;

            if ($query->have_posts()) {
                while ($query->have_posts()) {
                    $query->the_post();
                    $resourceCount++;

                    $post_type = get_post_type();
                    $post_type_object = get_post_type_object($post_type);
                    if ($post_type_object) {
                        $post_type_display = esc_html($post_type_object->labels->singular_name);
                    }
                    ?>
                    <div class="cell small-12 medium-4 large-3">
                        <?php
                        $is_downloadable = get_field('is_downloadable');
                        $asset_redirect = get_field('asset_redirect');
                        if ($is_downloadable) {
                            $download_link = get_field('download_link');
                            $resource_url = $download_link['url'];
                        } else if ($asset_redirect) {
                            $resource_url = $asset_redirect;
                        } 
                        else {
                            $resource_url = get_permalink();
                        }
                        ?>
                        <a class="asset-block <?php echo ($post_type); ?>" href="<?php echo $resource_url; ?>">
                            <i class="icon-<?php echo $post_type; ?>"></i>
                            <p class="content-type"><?php echo ucfirst($post_type_display); ?></p>
                            <h4><?php echo wp_trim_words(get_the_title(), 20); ?></h4>
                        </a>
                    </div>
                    <?php
                }
            }
            ?>
            <div class="pagination">
                <?php 
                    echo paginate_links( array(
                        'base'         => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
                        'total'        => $query->max_num_pages,
                        'current'      => max( 1, get_query_var( 'paged' ) ),
                        'format'       => '?paged=%#%',
                        'show_all'     => false,
                        'type'         => 'plain',
                        'end_size'     => 2,
                        'mid_size'     => 1,
                        'prev_next'    => true,
                        'prev_text'    => sprintf( '<i></i> %1$s', __( 'Newer Posts', 'text-domain' ) ),
                        'next_text'    => sprintf( '%1$s <i></i>', __( 'Older Posts', 'text-domain' ) ),
                        'add_args'     => false,
                        'add_fragment' => '',
                    ) );
                ?>
            </div>
            <?php wp_reset_postdata(); ?>
        </div>
    </div>
</section>

Some context on this block:

              <?php
                $current_url =  "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
    
                $active_query_param = parse_url($current_url, PHP_URL_QUERY);
    
                if($active_query_param) {
                    $resourcesPostTypes = $active_query_param;
                }
                ?>

This block is basically coming from a query (website.com/page/?query)

and grabs it, query being a post type, and filters it.

What I’m finding is that the pagination appears, but when you click on pagination it doesn’t actually do anything.

Paginated pages are showing correct content but pagination links are not

Static pages doesn't work with paged query variable, they need the page variable.

This is the reason why your second code block makes the query work: it uses the page var when available.

However, your paginated links code always use paged:

...
'format' => '?paged=%#%',
...
So you are sending paged query var but looking for page var.

Solution is to make your format argument send page query var if used from a static page.

So I changed my code a bit to this:

<div class="pagination">
                <?php 
                    $var = is_page() ? 'page' : 'paged'; // <-- choose var here  
                    echo paginate_links( array(
                        'base'         => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
                        'total'        => $query->max_num_pages,
                        'current'      =>  max( 1, get_query_var($var) ),
                        'format'       => '?' . $var . '=%#%',
                        'show_all'     => false,
                        'type'         => 'plain',
                        'end_size'     => 2,
                        'mid_size'     => 1,
                        'prev_next'    => true,
                        'prev_text'    => sprintf( '<i></i> %1$s', __( 'Newer Posts', 'text-domain' ) ),
                        'next_text'    => sprintf( '%1$s <i></i>', __( 'Older Posts', 'text-domain' ) ),
                        'add_args'     => false,
                        'add_fragment' => '',
                    ) );
                ?>
            </div>

But it still wont paginate.

How do you do pagination on a static page with a dynamic post_type argument on a static page?