Get Posts or Terms from All Blogs in Multisite Network

How to query all posts or terms in a single loop within WordPress Multisite install. With working pagination.

Query All Network Posts

If you're familiar with WP_Query class, you will be stunningly surprised. Network_Query is its multisite analogue.

$args = array(
	'posts_per_page' => 50,
	'orderby' => 'name',
	'order' => 'ASC'
	// all WP_Query arguments are supported including meta_query, tax_query etc.
$network_query = new Network_Query( $args ); // just like WP_Query!
if( $network_query->have_posts() ) :
	while( $network_query->have_posts() ) : $network_query->the_post();
		// $network_query->post is a post object - print_r( $network_query->post ) to find out more
		// use build-in functions like network_get_permalink() and network_get_post_thumbnail() to get post URL and thumbnail accordingly
		echo '<h3 id="post-' . $network_query->post->ID . '" class="blog-' . $network_query->post->BLOG_ID . '">
			<a href="' . network_get_permalink( $network_query ) . '">' . $network_query->post->post_title . '</a>
	echo 'No posts in the network for this criteria.';

Global Search

One search form. Multiple blogs search resuts.
You can search for posts, pages, tags, categories, custom post types and taxonomies.

Multiple blogs search results


Choose Post Types and Blogs to Index / to Query

post types and global search customization

Unlimited Blogs

Hundreds of blogs in your network? Not a problem — my plugin uses cron jobs to prevent server overload.

Unlimited number of blogs is supported


I'm always here if you need my help.
Please leave your question here or contact me if you need assistance with the plugin.

$args = array(
	'posts_per_page' => 50,
	'orderby' => 'name',
	'order' => 'ASC'
	// all WP_Query arguments are supported including meta_query, tax_query etc.
$network_query = new Network_Query( $args ); // just like WP_Query!
if( $network_query->have_posts() ) :
	while( $network_query->have_posts() ) : $network_query->the_post();
		// $network_query->post is a post object - print_r( $network_query->post ) to find out more
		// use build-in functions like network_get_permalink() and network_get_post_thumbnail() to get post URL and thumbnail accordingly
		echo '<h3 id="post-' . $network_query->post->ID . '" class="blog-' . $network_query->post->BLOG_ID . '">
			<a href="' . network_get_permalink( $network_query ) . '">' . $network_query->post->post_title . '</a>
	echo 'No posts in the network for this criteria.';

Global Multisite Search and Custom Post Queries

Just for 29$

Get the plugin or to learn more

So, How to Get All Network Posts in a One Query?

Click the links below to jump to a specific part of the documentation.

A few notes about plugin installation #

This plugin will index all posts in your Multisite Install with custom fields meta_query and terms tax_query. The posts and terms index will be stored in the following database tables.

phpMyAdmin: MySQL database tables with posts and terms indexed from all sites in a network.
MySQL database with the global content inside phpMyAdmin

Now some notes about the plugin installation.

  1. You can download the plugin by clicking the button in the top right part of the screen.
  2. By default this plugin will index only the new posts you publish. If you want to add to the index your old posts, go to Settings > Network Index and then switch to Rebuild Index tab.
Go to the Rebuld Index tab if you want to add your old posts to the network index.
That’s where you can completely rebuild the index

One important thing to know — when you rebuild your global index, it may take a time — how much — depends on the size of your Network. Maybe 10 minutes or maybe a hour.

Example 1. Just Get the Posts like WP_Query #

Let me introduce you the awesome Network_Query class — it works just like WP_Query but for all the network websites and supports all the same parameters + blog_id parameter (I will show this parameter in use in the next example).

Now let’s begin with something simple.

$network_q = new Network_Query('posts_per_page=5'); // display 5 latest global posts
if( $network_q->have_posts() ) :
	// run the loop for each post
	while( $network_q->have_posts() ) : $network_q->the_post();
		// we just get post titles
		// but you can print_r( $network_q->post ) to view all post data
		echo '<h3>' . $network_q->post->post_title . '</h3>';
else :
	echo 'No posts found for this criteria';

Something a little more interesting.

// Network_Query parameters
$args = array(
	'posts_per_page' => 14,
	'orderby' => 'name',
	'order' => 'ASC',
	'meta_query' => array(
			'key' => 'featured', // we display only posts with custom field 'featured' = 'on'
			'value' => 'on'
$network_q = new Network_Query( $args );
// if there are posts, then print <ul>
if( $network_q->have_posts() ) :
	echo '<ul>';
	// run the loop
	while( $network_q->have_posts() ) : $network_q->the_post();
		// the get_permalink() function won't work without switch_to_blog()
		// you can use network_get_permalink() instead but it is a little slower
		switch_to_blog( $network_q->post->BLOG_ID );
		// you can obtain the post title from $network_q->post object
		echo '<li class="post-' . $network_q->post->ID . ' blog-' . $network_q->post->BLOG_ID . '">
			<a href="' . get_permalink( $network_q->post->ID ) . '">' . $network_q->post->post_title . '</a>
		// restore_current_blog() to switch to the previous (!) website
	echo '</ul>';
network_reset_postdata(); // add it after the loop if you plan to use Network_Query multiple times on the page

Some comments:

  • In the loop we obtain $network_q->post object — it has all WP_Post object parameters with $network_q->post->BLOG_ID, the ID of the network blog.
  • If you need to do something and the WP_Post object is not enough for your purposes, then use the switch_to_blog() function – it allows you run any WordPress loop functions like get_the_post_thumbnail(), get_permalink() etc. Just do not forget to pass Post ID into these functions.
  • We need restore_current_blog() to cancel the switch_to_blog(), the function switches us to the previous blog — so, use it in a loop.
  • The network_reset_postdata() works similar to wp_reset_postdata().

The next very important feature of the plugin is global search. And you can search not only for posts and pages (post types), you can also perform search for categories and post tags (taxonomies).

Starting with the plugin version 4.4 it is even not required to do anything in the code in order to enable a global search. Just go to Settings > Network Index and then proceed to the Global Settings tab.

If you use the widget option, the global search widget will appear in Appearance > Widgets, or if you would like to replace the default search results, you should also proceed to the Sites admin page and turn it on there as well.
If you use the Widget option, the Global Search Widget will appear in Appearance > Widgets, or if you would like to replace the default search results with the global ones, you should proceed to the Sites admin page and turn this feature on there for each site individually.

With the code you also can:

  • Use WordPress default search engine across the whole network. I mean s= parameter of the Network_Query class.
    $args = array(
    	's' => 'Seach query'
    $query_search = new Network_Query( $args );
  • Search for posts by their custom fields values — meta_query parameter of the Network_Query class.
    $args = array(
    	'meta_query' => array(
    		'relation' => 'OR',
    			'key'     => 'key1', // key1 must contain "wordcamp"
    			'value'   => 'wordcamp',
    			'compare' => 'LIKE'
    			'key'     => 'key2', // OR key2 must contain "wordpress"
    			'value'   => 'wordpress'
    			'compare' => 'LIKE'
    $query_search = new Network_Query( $args );
  • Search terms by part of their titles and descriptions.
    $network_cats = network_get_terms('category', 'description__like=wordcamp');
    $network_cats = network_get_terms('category', 'name__like=wordpress');

In full global search tutorial I will explain you each of the above examples and show how to replace standart WordPress search form and results page with the global one.

Everything else is like in WP_Query.

Example 3. Get Posts only from the specific blogs in a network. Choose post types to index / to query #

Actually you can:

  • pass post_type or blog_in parameter to the Network_Query() class,
  • configure it in settings (globally for the whole network, or for each blog separately).
(string|array) It is default WP_Query parameter and I suppose you should already know how it works.
$args = array( 'post_type' => array( 'post', 'page' ) ); // get only posts and pages
(int|array) Specify the IDs of the blogs you want to query posts from.
$args = array( 
	'post_type' => 'post', // only posts
	'blog_id' => array( 1, 3 ) // only from blogs 1 and 3

Do not know where to get blog ID? Not a problem — my plugin will show blog ID column in your network dashboard Sites > All sites.

Column with Blog ID on the All Sites page
Plugin automatically adds the Blog ID column to the table with the all websites.

You should also know one thing about post_type query parameter — it will work only for indexed post types, for example here I added to the index the attachment post type in the plugin settings:

Add the attachment post type to global network index.

And as I mentioned before, the post types for indexing can be configured individually for each network website. To do this, in your multisite dashboard go to Sites > All sites and click Edit link under the Indexing tab.

Here you can configure what post types to index for each blog individually.
For each blog you can choose what post types to index or completely disable indexing.

Example 4. Query Network Posts with Pagination #

It is always very important for me to implement the pagination for network posts. And this is the simple way how you can do it:

global $wp_query;
// get the current page number from $wp_query, I mean the URL parameter, i.e. /page/2
$current_page = (get_query_var('paged')) ? get_query_var('paged') : 1; // you can use $wp_query->query['paged'] as well
// similiar to query_posts()
$network_q_posts = network_query_posts( array('posts_per_page' => 3, 'paged' => $current_page) ); 
// run the loop
foreach( $network_q_posts as $network_q_post ) :
	// we need it to work with get_the_post_thumbnail() and get_permalink()
	switch_to_blog( $network_q_post->BLOG_ID );
	echo '<li>' . get_the_post_thumbnail( $network_q_post->ID ) . '<a href="' . get_permalink( $network_q_post->ID ) . '">' . $network_q_post->post_title . '</a></li>';
	// switch back
// we should change the global $wp_query value to work correctly with pagination
$wp_query = $GLOBALS['network_query'];
// I use the popular WP PageNavi plugin
// reset the $wp_query

If you have problems with this example, you can read full detailed tutorial here.

Example 5. Get categories, post tags globally using get_terms() analogue #

My plugin allows you to get not only post types but taxonomy terms as well. It can be implemented easily with network_get_terms() (click the link to view detailed tutorial).

And here is a simple example:

$network_categories = network_get_terms('category', 'orderby=name&hide_empty=0');
if( $network_categories ){
	echo '<select>';
	foreach ( $network_categories as $network_category ){
		echo "<option value='{$network_category->term_id}'>{$network_category->name}</option>";
	echo '</select>';
in this example is obvious that
$network_category->name - category name,
$network_category->term_id - category global unique ID across the network
but you can get more info about the category if you look into the object using
print_r( $network_category );

4.4.1 – December 5, 2016

  • Added: network_get_term() function, the get_term() equivalent. The first parameter is $blog_id.

4.4 – December 4, 2016

  • Now you can completely replace the website default search results with the global network search results in the plugin settings without code at all.
  • As an option you can use both default and global search widgets in your website sidebar.

4.3.1 – November 15, 2016

  • Fixed: Warnings when indexing post meta.

4.3 – November 7, 2016

  • Improved: Plugin option pages are optimized for both new and old versions of WordPress.
  • Improved: Plugin performance in /wp-admin/.
  • Fixed: Problem with database tables, when default WordPress database has uncommon columns.
  • Fixed: Problem when saving blog index settings caused by WP-Cirrus plugin.

4.2 – September 23, 2016

  • Bug fixes.
  • Plugin update improvements.


  • Now the blog_id parameter of Network_Query supports array values.


  • Fixed redirect location for manual updates check.


  • Code optimization and UI improvements.


  • You can now get terms (categories, post_tags etc) from all blogs in Multisite network in a one loop using network_get_terms() function.
  • Changes in plugin update mechanism.


  • Changes in plugin update mechanism.

Comments 60

  • Purchased the product and initiated full index. Love the simplicity.

    I have a page that uses WP_Query command to display post. I tried replacing the WP_Query command with your Network commands and was unable to get the code to resolve.

    I was under the impression the code supported WP_Query implementation techniques.

    Could you point me in the right direction?


    • MishaAuthorMay 7, 2017 at 09:05

      Hello Van,

      could you please provide me more details:

      1.You just replaced WP_Query with Network_Query, right?
      2. What did you receive? No posts or incorrect result?
      3. What $args array do you use for that WP_Query loop?
      4. Have your posts been indexed well?

  • Louis-Philippe LampronApril 27, 2017 at 20:04

    Hi !
    WE installed your plugin yesterday and its very fine!

    Great thanks!

  • Felipe VolpatoApril 20, 2017 at 06:04

    Hello, how are you?

    Sorry for my English, which sucks.

    I’m installing it to display the post_types of my network on the main site. Can I include a field to differentiate other sites? If so, how can I do this? What I need is to display the site’s slug inside a box.

    Thank you.

    • MishaAuthorApril 20, 2017 at 08:04

      Hello, I’m fine, and you? :)

      If you use Network_Query, you can do it with BLOG_ID property, example:

      $network_q = new Network_Query( $args );
      echo '<div id="blog_id_' . $network_q->post->BLOG_ID . '">' // it will be #blog_id_1, #blog_id_2 etc

      Please, let me know if everything is clear for you.

      • Felipe VolpatoApril 20, 2017 at 19:04

        Thanks for the quick response.

        I ended up doing what I need and I still implemented with the path of the blog. With that I identified my post in the best way.

        Your plugin saved me hours of programming.

        Congrats on the job! Thank you.

  • Marcos AcostaApril 18, 2017 at 00:04

    Great plugin

    Couple of questions

    How can i combine to search the post and tags and categories at the same time

    also is there a way to add the domain of the multisite

    • MishaAuthorApril 18, 2017 at 07:04

      Hi Marcos,

      thank you!

      Yes, you can try these params:

      $args = array(
      	's' => '', // your search query
      	'tax_query' => array(
      		'relation' => 'OR', // you can use AND if both conditions are required
      			'taxonomy' => 'post_tag',
      			'field' => 'id', // you can get them by slug as well
      			'terms' => '' // tag ID or an array of IDs
      			'taxonomy' => 'category',
      			'field' => 'slug', // or by id
      			'terms' => '' // category slug or an array of slugs
      • Marcos AcostaApril 18, 2017 at 11:04

        it does not pull any articles when you search a category or tag name just pulls
        a post that contains the searched term in the content

        $args = array(
        	's' => get_search_query(), // your search query
        	'tax_query' => array(
        		'relation' => 'OR', // you can use AND if both conditions are required
        			'taxonomy' => 'post_tag',
        			'field' => 'id', // you can get them by slug as well
        			'terms' => '' // tag ID or an array of IDs
        			'taxonomy' => 'category',
        			'field' => 'slug', // or by id
        			'terms' => '' // category slug or an array of slugs

        am i missing something in the search query

        • Marcos AcostaApril 18, 2017 at 12:04

          Also any way to add authors

        • MishaAuthorApril 18, 2017 at 20:04

          Hmmm… It works on the base of default WordPress search and the default search allows to filter the results by category or by tag.

          Do not you forget to specify the terms parameter?

          You can also try to play with s, cat, tag and tax_query parameters – you can find their description in WP_Query official documentation.

  • Hi I have a multisite instalation with three sub sites apart from my primary so in total i have four websites in wordpress multisite installation now basicaly what I need is I want to show recent posts on several pages with only selected categorey ..

    how to make post categories global for all multisite and how can I show filtered / selected / categorey specific posts on my pages via visual composer … if its posibles with your plugin please let me know..

    • Hi Amara,

      the plugin indexes all websites categories as well. You can easily show posts filtered by categories via Network_Query class (all examples are above).

      Not sure if Visual Composer allows to use PHP in its widgets. But I think I can help you with some custom work and create a Visual Composer widgets for my plugin. If you’re interesting in it, please contact me.

      • Thanks for the reply ..
        Ya ! Its sounds good we already have Visual Composer widgets for post crousel (Masionary | Flat | List | Crousel) format so is it posible to use these visual composer modules ..

        So that wherever I want to list the post as a blog list .. I will just select the categorey or will use tags..
        for filtering the list..

        If its the way what will be the process to integrate and how can we proceed.


  • Love the plugin! It’s working great so far.

    One question:

    I’m using the Global Network Search to search all sites on my main site, and as each post goes through the loop on search.php, I need to get the tags and store as a variable, but I can’t do it. The only thing I can do is the_tags(), which displays the tags as links. I don’t want to display or link to tag archive — I just want to store the tags as an array and do some PHP with that information.

    Can you help me with this?

  • Hello,
    we would like to purchase your global multisite plugin. But we have a confusion.
    We are using CMS Commander which integrates 3 of our single websites into one. They are acting as multisite in this sense.
    now we want to search globally from 3 of our websites

    Can we use your plugin in this scenario ? if not then, do you have any alternate solution for us?

    • Hi Jewel,

      my plugin works only with WordPress Multisite.

      You could integrate your websites into a single multisite network first. After that you can use my plugin.

  • Mohammed AbdulmajeedJanuary 21, 2017 at 03:01

    I’ve been looking for a plugin like this for my Easy Digital Downloads eCommerce site for a long time, I wanted to show all my products from my sites on the networks on the homepage so users can easily find what they were looking.

    I’ve tried another plugin but couldn’t get it to do what I wanted.

    After purchasing the plugin I reached out to Misha and he has helped me set up so my archive page shows all the products on my network. He is professional and understanding.

  • Lewis Astell-BrookJanuary 16, 2017 at 21:01

    Misha has been a massive help! He’s gone above and beyond to get not only the plugin integrated but also semi-related search functionality – As well additional custom work which we paid for.

    Very prompt communication, professional and most importantly a very sophisticated plugin.

    Highly recommended!

  • Clayton CollieJanuary 13, 2017 at 23:01

    Great plugin, great support. Extremely patient and responsive. I had an issue with pagination and Misha was very helpful in troubleshooting my code and adding a custom filter. Can’t thank him enough!

  • Hello,

    Is this plugin compatible with Advanced Custom Fields? Also, if I want to display custom post types from a certain site, is it required for the site I want to display it on to have that specific custom post type registered?

  • Is there a get_term equivalent in the plugin?

    • Hi Trevor,

      Currently there are only network_get_terms() function. I will add network_get_term() for you within 12 hours.

    • The network_get_term() has been added. It is the get_term() equivalent for a multisite, the first function parameter should be a blog ID.

      network_get_term( $blog_id, $term, $taxonomy, $output, $filter );
  • How long should I wait after clicking the Rebuild Index button, and what is the indication that it has finished? I have waited 2 hours to rebuild the index for 48 sites with about 5,000 posts.

    • Hello,
      When the rebuilding is finished, the message “Indexing is currently in process” will disappear.

      I’m not sure about the exact time of indexing for 5,000 posts, but you shouldn’t wait for it on the same page — it processes in a background mode.

      • Thank you. It did update and took several hours, running in the background, as you said. I was able to follow the progress on the Statistics tab.

        On a separate note, I’m having trouble getting the function network_get_post_thumbnail() to work. I use the example query you have posted and place the function in the loop, but I get nothing. Also, I don’t see a post_thumbnail when I print_r($network_query)… Can you provide an example of how to pull in the thumbnail?

        Also, is there some documentation that lists all the “network” functions available for this plugin?


        • Currently I’m working on the full documentation and I hope to complete it soon.

          Post thumbnails are stored neither in post objects $network_post nor in the queries $network_query.

          At this moment the fastest and the optimal way to obtain the thumbnails, URLs or the attached terms is with using of switch_to_blog() function.

          while( $network_q->have_posts() ) : $network_q->the_post();
          	switch_to_blog( $network_q->post->BLOG_ID );
          		echo get_the_post_thumbnail( $network_q->post->ID, 'full' );
  • Thanks Misha;
    The upgrades on your plugin are phenomenal. This puts it over the top and well worth the price of admission. I’d give it five stars on wp if it was possible.

  • Mish,
    I’m interesting in your Global MU search plugin.
    I read usage note for this plugin.
    I want to ask the “Rebuild Network Post Index”
    It looks like that clicking Rebuild button gathers the data of post, page etc in the network.
    That means … Do I have to click the rebuild button averyday, if there is new post etc avery day?
    Is that mean I can’t find the new post, pages before Rebuild?

    • Hello,
      no, you have to click the rebuild button just one time — after the plugin activation.

      All the new posts, pages etc will be indexed automatically.

  • Do you network activate it or on a per site basis.

  • Excellent plugin that was just the solution we were looking for in our multisite network! Excellent customer support. Prompt, courteous, & professional!

  • Marc WielandOctober 25, 2016 at 12:10

    Excellent plugin. It prevented me from a lot of work.
    Just install, add post type inside the settings, index and adjust the loop in the theme. So simple and it works without hassle. Support is great and the response time is very low. Nice work Misha.

  • Hats off to Misha! We’ve been looking for a plugin that searches across our networked sites. Excellent plugin and excellent support. We are very happy with the results.

  • Great job for a multisite, with a small customize to be perfect. Misha is a great developer :)

  • We did not install the plugin yet but Misha is very reactiv, professional and sympathetic ! Recommanded :)

  • Davide De MaestriSeptember 8, 2016 at 12:09

    Great plugin and amazing support, Misha is a really good WP Developer and kind person. Really appreciated!

  • Hello, I just bought the plugin and I have a wpml multisite multilanguage website. I noticed that posts from other languages are between the default language.

    This is not supposed to happen, I want to switch manually to a language and only want to see posts in that language.

    Please help

    • MishaAuthorAugust 10, 2016 at 16:08

      if I understand you properly, currenly all the posts (all languages) are in the index.

      Could you tell me please where do you want to print the posts and how?

      • Yes Misha, that is correct.

        I’m hosting a local wordpress environment. This is the query I use:

        $network_q = new Network_Query(‘posts_per_page=14&orderby=post_date&order=DESC&post_type=page’);

        After that I use the usual loop:

        if( $network_q->have_posts() ) :…. etc.

        • MishaAuthorAugust 10, 2016 at 16:08

          I think you can use one of the following:

          1. Set blog_id as Network_Query paramater

          $args = array(
          	'blog_id' => array( 1, 2 ), // one or more blog IDs to INCLUDE
          	'posts_per_page' => 14,
          	'orderby' => 'post_date',
          	'order' => 'DESC',
          	'post_type' => 'page'
          $network_q = new Network_Query( $args );

          2. Skip the loop if blog ID doesn’t match your task

          while( $network_q->have_posts() ) :
          	if( in_array( $network_q->BLOG_ID, array( '3', '4' ) ) {  // in array specify blog IDs to EXCLUDE
          • That’s not my problem. I want all my blogs, I sometimes have multilanguage posts in 1 blog.

            Here is my problem:

            Some blogs have posts in different languages. I use WPML for it. when I normally use WP_Query it looks at the current language and modifies the query, so it only fetches posts in the current language.

            But when I use Network_Query I get posts in 2 languages, it doesn’t look at the current language the user selected.

            Do you understand?

          • MishaAuthorAugust 10, 2016 at 19:08

            I don’t use WPML for translations, so Im not sure that I can give you a proper advice.

            I think you just need to find out how WPML tweaks WP_Query and then to apply that changes to Network_Query or you can give me the information about it (for example if WPML tweaks it by custom fields or you can say me the name of the action hook) and I add this feature to the plugin by myself.

  • Hi,

    Does the plugin have to access WP_Cron from the outside? Our Multisite network is a closed network (hidden behind VPN) and it is not possible to access from the outside without having logged into VPN.

  • Hrvoje KrbavacJune 17, 2016 at 16:06

    Well done Misha! Contact me if you wish to work on one bigger WP project with me. :)

    • Hrvoje KrbavacJune 17, 2016 at 17:06

      Sorry but you have made a mistake.. at least my opinion :)
      Your plugin works only if you install it and after activation insert terms/categories…
      You should upon activation go through all terms and update your MySQL tables.

      • MishaAuthorJune 18, 2016 at 09:06

        Hello :)

        No, it indexes all the network terms/posts/categories etc. It just doesn’t index all of them at once — just to prevent overload of your blogs.

        So, if WP_Cron is working on your website (on the most of WordPress blogs it works well) the previously created terms and posts will be indexed soon.

  • Perfect plugin, beatifully implemented ;)
    Support is also fast and pleasant. Author is great professional.

    I recommend, it is really worth the money!!!

  • Excellent customer service.
    You need to understand and implement the code examples

Leave your question or feedback

Please, enter a comment
Please, enter a name
Incorrect email

Some of the companies that use this plugin

Make Do (Barnsley, UK) Modularte (Hanau, Germany) Connective DX (Sydney, Australia) Old River Creative (Woodstock, Virginia, USA)
DotDev (Australia, Brown Hill) Miux (Switzerland, Chur) PurposeWP (United States, Fort Worth) Rovecom (Netherlands, Hoogeveen)

14-Day Money Back Guarantee

Secure Checkout. Instant Download



$129 one-time payment
  • Lifetime priority support
  • Lifetime updates
  • Unlimited websites


$29 one-time payment
  • 2 weeks/support
  • 1 year/updates
  • Unlimited websites

View my refund policy here

The plugin is a one-time purchase which includes a license for plugin updates and support. To continue receiving updates & support after your license has expired you may renew at a discounted rate of 50%.