WordPress MU: Cross-Posting with "switch_to_blog()"
This weekend I tackled a MU template challenge that I’d been procrastinating on because I thought it would be really tough. The problem, simply, was that I needed to display posts from one MU blog on another blog within my MU installation.
The answer: a handly pair of WordPress MU functions called switch_to_blog() and restore_current_blog(). Using these functions, you can jump around temporarily between MU blogs, allowing you to pull posts — or anything else, I presume — from wherever you like. It’s as easy as:
<?php // do some stuff on the current blog... switch_to_blog(9); // ...do some stuff on the other blog... restore_current_blog(); // ...do some stuff back on the current blog ?>
Read on for more detail…
Searching for and Discovering WordPress Functions
When I am trying to learn something new about WordPress’s code, the first thing I do is open the whole WordPress directory the wp-includes directory (where most of the interesting functions live) as a Textmate project. That lets me do two important things:
- Search through all the files at once, using Find In Project (Cmd + Shift + F…) — useful for following the labyrinth of function calls.
- Within a single file, use the function drop-down menu in the Textmate window footer — useful for quickly scanning all the function names.
To solve this problem, I had very little idea what to look for. At first, I examined the get_posts() function in /wp-includes/post.php, thinking I’d be able to pass in a blog ID, and just get posts from a specific blog. That yeilded some interesting information, but I couldn’t find any way to get another blog’s posts simply. So I switched tracks and focused on the file /wp-includes/wpmu-functions.php, figuring there must be some hints amongst the MU-specific code.
Didn’t take much looking to discover switch_to_blog()… not exactly what I had been looking for, but I figured it was worth a shot.
An Example of Switching Blogs
After a little theme massaging, here’s what I ended up with, and it worked perfectly!
<?php
$other_blog_id = 1;
// get posts from current blog
$self_posts = get_posts(array(
'numberposts' => 4
));
// switch blogs
switch_to_blog($other_blog_id);
// get some posts from the other blog
$other_posts = get_posts(array(
'numberposts' => 4
));
// ok, we're done with that other blog
restore_current_blog();
// merge the two arrays
$posts = array_merge($self_posts, $other_posts);
// sort the entire array by date
function sort_posts_array_by_post_date($a, $b) {
if ($a->post_date == $b->post_date)
return 0;
return $a->post_date < $b->post_date ? -1 : 1;
}
usort($posts, 'sort_posts_array_by_post_date');
?>
That left me with a sorted array of posts, from two separate blogs. All I had to do then was loop through and output all the post content…
One More Gotcha… Switch Again For Post Template Functions Use get_blog_permalink()
Everything looked ok, but a little testing revealed that permalinks weren’t working… they were linking to the wrong URL. So, I had to switch back to right blog for each post before using standard WP template functions, like this:
UPDATE: @Bira pointed out in the comments that there’s a function called get_blog_permalink() that seems to do exactly what I wanted… get the permalink to a post in another blog. So I deleted the code sample below. Instead of switching back-and-forth for each post, it would make sense to stash the blog id for posts when you retrieve them from the other blog, then use it when calling get_blog_permalink().
Comments(6)