Ask your WordPress questions! Pay money and get answers fast! (more info)

Which way to pull posts from mainsite to subsites on multisite WordPress

  • SOLVED

Hello all,

I have to pull posts from 3 post types from my mainsite onto my subsites, on my wordpress multisite. In total I will be running about 12 cross site queries on each sub site. I have found three different approaches that don't clone posts from the main site to the subsites and now need help deciding which method to pick.

*note I know multisite wasn't intended for this, but I haven't found an appropriate solution to what I need.

The functions I would like to run in the cross network queries are:

get_post_meta();
the_title();
a social network bar template tag: get_social_bar();
the_post_thumbnail();
a custom like button template tag: my_like_button();

*note plugins will be installed network wide


Solution 1:
[[LINK href="http://codex.wordpress.org/Function_Reference/switch_to_blog"]]switch_to_blog(); [[/LINK]] Wordpress warns "It's to expensive of a query to run on the front end". I'm really not sure what that means and would like some explanation. I've seen many stackexchange posts and this post titled [[LINK href="http://scotty-t.com/2012/03/13/switch_to_blog-is-an-unfunny-nightmare/"]]switch_to_blog is an unfunny nightmare.[[/LINK]] Most stackexchange posts don't approve of this function, where the switch_to_blog is an unfunny nightmare post claims: " If your site switches from one blog to the next and doesn’t
intermingle content – you really don’t have much to worry about after your initial setup. But in almost all cases, if you want to start using switch_to_blog() to co-mingle content from multiple sites inline, get ready to do some debugging!". I don't think I'll be co-mingling content seeing how I'll only be getting posts from the mainsite. So given how many functions I would like to use and the amount of queries I would like to run on each sub site from the mainsite; Would you suggest that I use switch_to_blog to pull posts?

Solution 2:

I found a post on [[LINK href="http://www.htmlcenter.com/blog/wordpress-multi-site-switching-blogs/"]]htmlcenter[[/LINK]]<blockquote> that uses a method that modifies the $wpdb object so that it queries a different set of tables in the database.</blockquote> The problem is I don't know the implications of this method since I'm not strong at PHP, or SQL. Another problem is that since I'm not strong with SQL I would probably have to pay a developer to write about 5 custom queries. Would you suggest this be the best way to go? Is there implications that could potentially do harm to the site using this code. Is it better that I would use this over switch_to_blog? Ideally I'd like to use switch_to_blog but just worry.

Solution 3:

wpmu.org has a plugin called [[LINK href="https://premium.wpmudev.org/project/post-indexer/"]]post indexer[[/LINK]]. This plugin essentially allows selected post types from specified sites across the network to be copied into one spot in the database. This is to be used along with other plugins like global posts widget (gets recent posts across a network). The post indexer has basically its own version of the WP_Query called [[LINK href="http://pastebin.com/2FmGkXbF"]]network_post_query()[[/LINK]]. network_post_query essentially allows for all of the same parameters as WP_Query, plus a parameter that allows you to query posts on which site in the network you want to get posts from. The problems are:

- [[LINK href="http://pastebin.com/fatw1Cv6"]]It has its own built in template tags that take the place of normal template tags[[/LINK]] eg: the_title(); would be network_title();
- It's also missing a few functions that I would need like the post thumbnail, like button, social bar. (I could probably build them in)
- I've heard it can be a little bit slower to display posts, but that might be with a network that's indexing a lot post types from a lot of different sites.
- it uses switch to blog to convert a few template tags like the_permalinks(); into network_permalinks(); eg:
function network_get_permalink( $blog_id = 0, $id = 0 ) {

$post = &network_get_post( $blog_id, $id );

if(!empty($post)) {
switch_to_blog( $post->BLOG_ID );
$permalink = get_permalink( $post->ID );
restore_current_blog();

return $permalink;
}
}


I have also just found out that the post indexer plugin in slow because something to do with <blockquote>post-indexer relies on wordpress cron, the cron is fired more often the more people that visit your site itself, so the more visitors you have, the more the cronjob will fire.</blockquote>

Again I am leaning more towards wanting to use switch_to_blog, simply because of my experience levels. As said before, I will only be pulling posts from 3 post types on my mainsite, and won't be crossing content from a variety of sites. I could probably make the functions needed easily for post indexer. I understand that because this is the simple solution, it may not be the right one. Which is why I need your help. What do you think would be the most appropriate solution, given all of the information I provided?

Thank you for all of your help!

Answers (3)

2014-10-31

John Cotton answers:

There's no single correct answer to this, it comes down to your specific needs and circumstances.

Personally, I would lean away from anything that copies content. Why would you want two sets? What happens when you want to update a copied post?

switch_to_blog is "expensive" in the sense that a lot of cache updating has to been done to shift state from one set of database tables to another.

Given that you know where you source data is (in the first/top level site), I would have thought going to the SQL route is the best for you.

You're right that that means a set of custom SQL queries (which from a maintenance/upgrade point-of-view is not so desirable) but, if you stick as closely as possible to the structures provided (eg use $wpdb to access tables) that shouldn't be too much of an issue.

I can't say what those SQL queries should be since I don't know the circumstances in which you want to pull posts, or which posts you would want to pull.

But, as a principle, I would say your option 2 is the best path.


Chris comments:

Thank you very much for your valuable advice John!

2014-10-31

Fahad Murtaza answers:

I'd second John on this one. I never copied content, like never!

Just use custom SQL or hire someone to do it for you.

2014-10-31

Dbranes answers:

According to the [[LINK href="http://codex.wordpress.org/Version_3.5"]]WordPress 3.5 changelog[[/LINK]] (december 2012):

<blockquote>Multisite's switch_to_blog() is now significantly faster and more reliable</blockquote>

so some of the complaints are prior to that.

Other problems can arise because this is not a total switch.

Since you're only generating data from a single blog, one of the simplest thing you could do would be to use the

update_site_option( 'wpq_data', $data );

function to save the generated HTML data. Then this can be accessed from the sub blogs with

get_site_option( 'wpq_data' );

You could also use

update_option( 'wpq_data', $data );

on the main blog and then

get_blog_option($blog_id, $setting, $default);

for your sub blogs.

Since you don't want to run expensive updates on every page load, you might use for example <em>wp-cron</em> or <em>linux cron</em> for time precise updates.

Similarly you can also use the <em>set_site_transient()</em> and <em>get_site_transient()</em>, but then you would have to take care of the situation when the transient expires.


Chris comments:

Hi Dbranes,

So would I basically just set a query in a function and then save that as $data?

example:

function prepare_recent_post_data(){
//WP_Query Loop
}
$data = prepare_recent_post_data();
update_site_option( 'recent_posts_data', $data );


Do you think that would cause trouble when my users hit the "like" on a single post? All the social network like/ share counts should be able to stay up to date as well to right?

Thank you for your advice so far!