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:

  1. Search through all the files at once, using Find In Project (Cmd + Shift + F…) — useful for following the labyrinth of function calls.
  2. 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().

6 Comments so far

  1. babelcomics on July 28th, 2009

    Thanks a lot for the interesting post, this is just what I was looking for. A way of multiblog-selecting for some theme sections.

    Thanks a lot, made my day :)

    Cathbad

  2. Ray on August 20th, 2009

    I tried using the switch_to_blog() function with widget sidebars… but wasn’t able to get this working.

    Are you able to use switch_to_blog() with dynamic_sidebar()?

  3. admin on August 20th, 2009

    Good question Ray. I haven’t tried it yet.

    I’m not sure when I’ll get around to messing with this, so if you find a solution, let me know.

  4. Xavier Riley on September 16th, 2009

    Thank you so much for posting this. I know you we’re just giving a tip off but knowing about this function helped me so much.
    Many thanks

    Xavier Riley

  5. Bira on November 3rd, 2010

    For the permalink, why not simply use get_blog_permalink?
    http://codex.wordpress.org/WPMU_Functions/get_blog_permalink

  6. Jason Tremblay on November 3rd, 2010

    @Bira Thank you! I wasn’t aware of that function. Looks like that’s the right way of handling the permalink… and it prevents additional switch_to_blog() calls, which I’ve heard can consume system resources if called repeatedly.

Leave a reply