How to Paginate in All Multisite Posts

Sometimes it is required to display the posts from all multisite network blogs on the homepage or on a separate page. And in this tutorial I will show you how to create a pagination for all network posts.

#WordPress Multisite  /    /   19

This tutorial consists of two simple steps. In the first step we create a pagination function and in the second step — the loop of posts.

Let’s begin.

Step 1. Pagination function #

Actually you can try to install any pagination plugin for WordPress and use its own functions. But why we should do this if WordPress since 2.1.0 has its own pagination function — paginate_links()?

And misha_pagination() is just my wrapper for it. You can insert the following code directly to your current theme functions.php. You can also make some customization of $args array if you want.

function misha_pagination( $query ) {  
	$args = array(
		'total' => $query->max_num_pages, // total amount of pages
		'current' => ( ( $query->query_vars['paged'] ) ? $query->query_vars['paged'] : 1 ), // current page number
		'show_all' => false, // set to true if you want to show all pages at once
		'mid_size' => 2, // how much page numbers to show on the each side of the current page
		'end_size' => 2, // how much page numbers to show at the beginning and at the end of the list
		'prev_next' => true, // if you set this to false, the previous and the next post links will be removed
		'prev_text' => '«', // ยซ
		'next_text' => '»' // ยป
	if( $args['total'] <= 1 ) // do not return anything if there are not enough posts
	return '<div class="navigation">
		<span class="pages">Page ' . $args['current'] . ' of ' . $args['total'] . '</span>'
		. paginate_links( $args ) .  
Pagination parameters explanation

Step 2. Get Multisite Network Posts with Pagination #

The second and the last step of this small tutorial.

Here is one thing you have to know — if you want to display posts (network posts or local posts, doesn’t matter) in a custom loop with pagination — I highly recommend you to use pages with custom page templates because of the URL issues.

The main advantage here is that any page with a custom page template can be set to be displayed on your website front page in Settings > Reading.

Multisite Posts on the Front Page

With the code below you can easily display the posts from all network blogs (Network_Query allows you to include only specific blogs to the query as well) on any WordPress page, with a custom page template or without it. And any page can be displayed on a front page.

Displaying network posts in category templates or in single.php isn’t a good idea but if you really need to implement it, leave a comment after this post and I will try to help you.

Network_Query() class is a really great thing — it works just like WP_Query() but works for all the blogs in your multisite network. WordPress code doesn’t have this class by default, it is the part of my plugin — you can get it here.

Actually without my plugin installed this example won’t work for you.

Insert this code anywhere you want to show the network posts with a pagination.

// get the current page number from $wp_query['query_vars'], I mean the URL parameter, i.e. /page/2
// (!) if you use the code on the front page, change PAGED to PAGE, e.g. get_query_var('page')
$current_page = (get_query_var('paged')) ? get_query_var('paged') : 1;
// this class is similar to WP_Query but works for multisite posts, my plugin is required, the link is above in this post
$multiquery = new Network_Query( array('posts_per_page' => 1, 'paged' => $current_page) ); 
// run the loop
if( $multiquery->have_posts() ) :
	while( $multiquery->have_posts() ) : $multiquery->the_post();
  		// we need switch_to_blog() to work with get_the_post_thumbnail(), get_permalink() and some other loop functions
		switch_to_blog( $multiquery->post->BLOG_ID );
		echo '<p>' . get_the_post_thumbnail( $multiquery->post->ID ) . '<a href="' . get_permalink( $multiquery->post->ID ) . '">' . $multiquery->post->post_title . '</a></p>';
		// switch back
	// print pagination, pass the query object as a required parameter
	echo misha_pagination( $multiquery );

Please, let me know in comments if you have any questions.

Misha Rudrastyh
About the author Misha Rudrastyh

Passionate about WordPress and snowboarding, creating websites for over 10 years! Let's work together — just contact me.

If you are a developer too, subscribe to my facebook page.

Comments 19

  • Hello.
    You can not display all of the articles of custom post archive.php.
    If you use the Paginate, contribution number of Main Site displays only.
    In the case of fixed page is perfect.

  • Clayton Collie

    Hi Misha,

    On your homepage, to get posts with pagination, you use a foreach loop like get_posts and then on this page you use the Network_Query class. You also use pagenavi on the homepage of the multisite plugin and then on this page you use a custom pagination function with the paginate_links core function. Which one should we use?

    I actually have the loop working with pagination using the Network_Query class BUT I am getting a 404 error on about half of my pages. (Running on version 4.2)

    I have posts_per_page at 10 and I have around 900 posts from 9 sites. Pagination shows all 91 page links but after about 50 or 51 I start getting 404 errors. Any idea what is going on?

    Also, I am not sure if I purchased this plugin a while back. Can you check? or

    • Hi,

      You can use any of these examples, but I recommend Network_Query and custom pagination function.

      Do you use custom network queries with pagination in page.php or page template files? Because if you add another loop to the category pages or into index.php, there will be a conflict with default WordPress loop for this page.

      I can not find your email, can you please tell me the date of purchase?

      • Clayton Collie

        Great. That is the function I am using along with you pagination function.

        I am using the Genesis framework. On home.php and author.php I remove the default loop then replace with the Network_Query loop. Should not be a conflict. I am in the process of rebuilding the index to see if that sorts it out. It is taking a little while due to number of posts.

        Note sure of my date of purchase. I’ve been working on this site for almost a year and half. I recently upgraded to 4.2 via the check update link from 4.1.1

        • Ok, I will try to explain you.

          Before any code of your theme, WordPress creates $wp_query, this query knows, how much posts should be displayed on the page, what to display. This query also knows if page is not exists (404).

          So, if you try to access /page/78, but $wp_query thinks that /page/55/ is the last page, no matter what you add to your theme files, it will be 404.

          Actually you can replace default loop with Network_Query loop on any page, but it is simple to do on page.php, and using page template files and much more harder to do on index.php, home.php, tag.php etc.

          Why harder? Because in this case you should trick WordPress about 404 error pages using pre_handle_404 filter (I will publish a post about this filter later).

          • Thanks for the info. In one your loops on this site, you load the global for wp_query then after the loop you modify it with the network_query object.

            Would that solve the problem?

          • I recommend you 3rd time to use a page template for your purpose. After that set it to homepage. That’s all – problem resolved.

            But if you do not like easy ways, trick the $wp_query using pre_get_posts or pre_handle_404 :)

  • Clayton Collie

    Seems as though it is not working now. Pagination is showing 78 possible pages for posts to appear but the last page to not be a 404 is

  • Thanks for the wonderful code. I need to display posts from all multisite blogs in the back-end, so that the editor can manage the posts in the wp-admin area like in the single site. How can we do it?

    • Hi again,

      Anyway, I’ve added this feature. More info is here. No ACF columns are supported, but actually you can edit plugin’s posts.php file a little for your needs.

  • Hi Misha,

    Thanks for this amazing plugin. I’m excited to implement it on my site.

    I’m having trouble getting the pagination working, though. As you suggested, I’m using a custom page template and have it set as my front page under Settings > Reading. On that custom page, I copied and pasted the code you have displayed above. I also copied the misha_pagination function into my functions.php file.

    While I do see the page number links at the bottom of my home page, clicking any of them just displays same first 10 posts. I deactivated all other plugins and even tried this using the twentyten theme to keep it simple, but I’m having no luck. Any suggestions?

  • Nevermind. I just saw your comment in the code.

    // (!) if you use the code on the front page, change PAGED to PAGE, e.g. get_query_var(‘page’)

    That fixed it.

  • I see on your site that Network_Query will accept all of the same arguments as WP_Query, but I’m having trouble getting the network query to exclude sticky posts. The code I’m using is below, but sticky posts are still being included. Can you help?

    $args = array (
    	'post__not_in' => get_option( 'sticky_posts' ),
    	'posts_per_page' => 10, 
    	'paged' => $current_page
    $multiquery = new Network_Query( $args );
    • Hi,

      get_option( 'sticky_posts' ) returns only sticky posts from your current blog/site where you use the query ๐Ÿ™ƒ

      • Is there a way that I could add an argument to the Network_Query that would exclude sticky posts from the results?

      • Yes, actually you can use the same post__not_in, but find a way to add sticky posts in one array common for all blogs.

        Or just use 'ignore_sticky_posts' => true.

Comments are closed.
If you need my personal help, please contact me. Contact me