WordPress Multiple Post Type Loop & Pagination by Shortcode

This article describe how to create multiple post loop with pagination by shortcode. You might have already know how to create post list with shortcode, here i am extending that with multiple occurrence 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'] = $_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>',
	    $html .= '</ul>';

    $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, as this wont effect any of the other pagination on the page. The shortcode can be used multiple times and pg will be increasing with a number, ex pg1, pg2 etc. But you can ofcourse define your own variable name ex: paginate_page, paginate_product, paginate_some or anything but not WordPress protected variables.


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