WordPress Multiple Post Type Loop & Pagination by Shortcode

This article describes how to create multiple post loops with pagination using a shortcode. You might already know how to create a post list with a shortcode, here I am extending that with multiple occurrences and pagination.

Multiple Post Type Loop & Pagination by Shortcode – Code

function w4dev_custom_loop_shortcode( $attrs ) {
    static $w4dev_custom_loop;
    if ( ! isset ( $w4dev_custom_loop ) ) {
        $w4dev_custom_loop = 1;
    } else {
        $w4dev_custom_loop ++;
    }

    $attrs = shortcode_atts( array(
        'paging'         => 'pg'. $w4dev_custom_loop,
        'post_type'      => 'post',
        'posts_per_page' => '5',
        'post_status'    => 'publish'
    ), $attrs );

    $paging = $attrs['paging'];
    unset( $attrs['paging'] );

    if ( isset( $_GET[ $paging ] ) ) {
        $attrs['paged'] = max( 1, absint( $_GET[ $paging ] ) );
    } else {
        $attrs['paged'] = 1;
    }

    $html  = '';
    $custom_query = new WP_Query( $attrs );


    $pagination_base = add_query_arg( $paging, '%#%' );

    if ( $custom_query->have_posts() ) :
        $html .= '<ul>';
            while( $custom_query->have_posts()) : $custom_query->the_post();
            $html .= sprintf(
                '<li><a href="%1$s">%2$s</a></li>',
                get_permalink(),
                get_the_title()
            );
            endwhile;
        $html .= '</ul>';
        wp_reset_postdata();
    endif;

    $html .= paginate_links( array(
        'type'    => '',
        'base'    => $pagination_base,
        'format'  => '?'. $paging .'=%#%',
        'current' => max( 1, $custom_query->get('paged') ),
        'total'   => $custom_query->max_num_pages
    ));

    return $html;
}
add_shortcode( 'w4dev_custom_loop', 'w4dev_custom_loop_shortcode' );

For pagination, we are using a custom query argument pg rather than the default page, so it won’t affect any other pagination on the page. The shortcode can be used multiple times and pg gets an increasing number, ex: pg1, pg2 etc. You can of course define your own variable name, ex: paginate_page, paginate_product or anything else, as long as it isn’t a WordPress reserved query variable.


Usage

The shortcode can be used with [w4dev_custom_loop] in your page or post content. Try copying the code into your theme’s functions.php or plugin file, then use the two shortcodes [w4dev_custom_loop] and [w4dev_custom_loop post_type="page"]. This will output a list of posts and a list of pages. You can paginate both lists without losing the other list’s pagination. That means, if you are on level 3 of the post list, and then navigate the page list to level 2, both lists will keep their offset correct.

Leave a Reply

Your email address will not be published. Required fields are marked *