admin管理员组文章数量:1122832
I have a multisite network of sites which should display blog content from each other if the blog post has a tag with the site name.
To gather all posts within the network I use the SWT (Sitewide Tags) plugin as it seems most efficient. I store all posts in the main site (blog id 1) and from my other sites I want to query the main sites posts table for posts containing a tag with the querying site's domain name.
I have working code in a page template (home.php
) - see below - but I understand the action pre_get_posts
are the way to go, but I can't seem to figure out how to change the table to query. Should I perhaps do a JOIN in the action posts_join
?
If my solution seems to be way more complicated than it should be, feel free to bash me with other suggestions :)
This is my current template code:
$tags = array(
'lundalogik-se'
);
switch_to_blog(1);
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$wp_query = new WP_Query(array(
'post_status' => 'publish',
'paged' => $paged,
'orderby' => 'date',
'order' => 'desc',
'tag' => implode(",", $tags)
));
while (have_posts()) : the_post();
[..]
How can I rewrite this in pre_get_posts
?
Note; as you see the tag I'm searching for is static at the moment, this will change to match the domain name + ccTLD of the querying site or something similar later on.
Note 2; I'd rather not use switch_to_blog()
since I read it's expensive but haven't found a best practice for querying other blogs inside a network. Should I set the table name to query manually instead?
I have read most posts both here, in blogs and in the Codex (WP_Query, pre_get_posts etc.) touching multisite querying but almost all talks of using switch_to_blog and restore_current_blog.
I have a multisite network of sites which should display blog content from each other if the blog post has a tag with the site name.
To gather all posts within the network I use the SWT (Sitewide Tags) plugin as it seems most efficient. I store all posts in the main site (blog id 1) and from my other sites I want to query the main sites posts table for posts containing a tag with the querying site's domain name.
I have working code in a page template (home.php
) - see below - but I understand the action pre_get_posts
are the way to go, but I can't seem to figure out how to change the table to query. Should I perhaps do a JOIN in the action posts_join
?
If my solution seems to be way more complicated than it should be, feel free to bash me with other suggestions :)
This is my current template code:
$tags = array(
'lundalogik-se'
);
switch_to_blog(1);
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$wp_query = new WP_Query(array(
'post_status' => 'publish',
'paged' => $paged,
'orderby' => 'date',
'order' => 'desc',
'tag' => implode(",", $tags)
));
while (have_posts()) : the_post();
[..]
How can I rewrite this in pre_get_posts
?
Note; as you see the tag I'm searching for is static at the moment, this will change to match the domain name + ccTLD of the querying site or something similar later on.
Note 2; I'd rather not use switch_to_blog()
since I read it's expensive but haven't found a best practice for querying other blogs inside a network. Should I set the table name to query manually instead?
I have read most posts both here, in blogs and in the Codex (WP_Query, pre_get_posts etc.) touching multisite querying but almost all talks of using switch_to_blog and restore_current_blog.
Share Improve this question asked Oct 28, 2013 at 11:28 Johan NordströmJohan Nordström 611 silver badge6 bronze badges 6 | Show 1 more comment3 Answers
Reset to default 2OK so for reference I ended up actually using switch_to_blog()
and restore_current_blog()
. I found no references whatever for querying multiple tables (except writing my own JOIN
-statements) when followed the source code for the action pre_get_posts
.
A lot of advice was given to skip restore_current_blog()
to save CPU-cycles but when I checked the source code for this I saw that it would cause a huge memory problem since the main thing restore_current_blog()
does is to pop the latest inserted object in a global array and this array would grow hugely with each switch_to_blog()
that one does not do a restore_current_blog()
on.
Please feel free to check the source code and also see @user42826's answer regarding this at https://wordpress.stackexchange.com/a/123516/14820.
For those who are interested, I ended up with transients both for the site-list and for the result to save both CPU-cycles and DB performance. I only needed data to be updated if it were stale (15 minutes or more of age). Only relevant bit of function included below:
$site_transient = get_site_transient( 'multisite_site_list');
if ($site_transient == false || LL_USE_TRANSIENTS == false) {
$using_site_transient = false;
// no cache available
global $wpdb;
// TODO: get prefix for wp tables
$site_list = $wpdb->get_results($wpdb->prepare('SELECT * FROM nw_blogs WHERE public = %d AND deleted = %d ORDER BY blog_id', 1, 0));
// set transient
set_site_transient('multisite_site_list', $site_list, LL_TRANSIENT_EXPIRES);
} else {
//log_msg("SITELIST - Transient found, using cached query..");
$site_list = $site_transient;
$using_site_transient = true;
}
//log_msg("$id - get_posts_from_network | tags: " . implode(",", $tags) . " | tag_slug__and: $lang_full");
$start = microtime(true);
// get blogpost transient, if existing
$post_transient = get_site_transient( 'limelight_recent_posts_' . $hash);
// if not, do query and save result as a transient
if ($post_transient == false || LL_USE_TRANSIENTS == false) {
$using_post_transient = false;
$blogposts = array();
foreach ($site_list as $site) {
switch_to_blog($site->blog_id);
$posts = get_posts(array(
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'desc',
'tag' => implode(",", $tags),
'tag_slug__and' => array($lang_full)
));
//log_msg("$id - get_posts_form_network | at site: $site->blog_id");
foreach ($posts as $post) {
//log_msg("$id - get_posts_form_network | at site: $site->blog_id | got post!");
$post->human_post_date = human_time_diff(get_post_time('U', false, $post->ID), current_time('timestamp')) . ' ' . __('ago', 'limelight');
if (isset($tagline_metabox)) {
$meta = get_post_meta($post->ID, $tagline_metabox->get_the_id(), TRUE);
$post->tagline = $meta['tagline_text'];
}
if (!isset($post->tagline) || $post->tagline == '')
$post->tagline = substr($post->post_title, 0, 20) . '..';
$post->post_date_timestamp = strtotime($post->post_date);
//$post->blog_id = $site->blog_id;
$post->blog_name = get_bloginfo('name');
$post->blog_url = get_bloginfo('wpurl');
$post->permalink = get_permalink($post->ID);
$post->author_name = get_userdata($post->post_author)->display_name;
//$data = get_userdata($post->post_author);
$blogposts[] = $post;
}
restore_current_blog();
}
// sort blogposts by post_date_timestamp, descending
array_sort_by_obj($blogposts, 'post_date_timestamp', SORT_DESC);
// pick five latest posts
if (sizeof($blogposts) > 5) {
$posts = array();
for ($i = 0; $i <= 4; $i++) {
$posts[$i] = $blogposts[$i];
}
$blogposts = $posts;
}
// set transient
if (LL_USE_TRANSIENTS)
set_site_transient('limelight_recent_posts_' . $hash, $blogposts, LL_TRANSIENT_EXPIRES);
Try the following:
add_filter( 'pre_get_posts', 'get_post_from_main_blog' );
function get_post_from_main_blog($query) {
global $wpdb;
$wpdb->posts = 'wp_posts';
return $query;
}
You may need to change wp_posts to your main blog's post table name.
Afaik there is no built in way to query posts of different Multisite instances, so you can only build a custom query, use "switch_to_blog" in a loop with all blogs, or use a custom WP_Query Class like this one: https://github.com/miguelpeixe/WP_Query_Multisite/
The last option just overrides WP_Query, so you can use it like this:
$query = new WP_Query(['multisite' => 1]);
Of course you would add other query params too. In this case, the WP_Query will search for the relevant items in the whole Multisite.
Btw, this only seems to work with regular posts, not with other post types.
Another option that works with other post types: https://github.com/ericandrewlewis/WP_Query_Multisite
本文标签: How would I use pregetposts to query another site for posts in my multisite network
版权声明:本文标题:How would I use pre_get_posts to query another site for posts in my multisite network? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736308671a1933748.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
pre_get_posts
doesn't return anything, it gets $query by reference and from what I can see he never attaches $test_obj to $query->something. Also, he's using switch_to_blog which I'd rather avoid if possible :). – Johan Nordström Commented Oct 28, 2013 at 12:26pre_get_posts
so I resorted toswitch_to_blog()
andrestore_current_blog()
. Note: I found advice saying I should skiprestore_current_blog()
but analyzing the code for those two functions I could see that it builds up a huge array taking up lots of memory if I do not "pop" eachswitch_to_blog()
with arestore_current_blog()
. – Johan Nordström Commented Mar 7, 2014 at 16:17