echo “Hello Again, World!”;

NOTE: This system has a new page — you can find it at http://striderweb.com/nerdaphernalia/features/virtual-multiblog/. I’ll leave this page up for historical purposes, but it’s closed to new comments. Comments are most assuredly open on the new page.

Greetings and salutations.

This is my second blog, which is here to serve as a repository for the really die-hard geekery that I feel just doesn’t belong in my regular blog. I discuss the reasons in a bit more detail over there, if you haven’t seen it.

I’ve been thinking about this for a few months, and have taken a couple weeks to get things going. The reason setting up this second blog has taken so long, and the reason my main blog has been virtually silent for so long, is that in the process, I did something kind of cool.

Let me step back for a moment. I am a true hacker at heart, in the traditional sense: I love to pull things apart and take a look. To see how they work and how they might work better. I’m also an avid Mac-head, and since the rise of OS X, I’ve been learning the ins and outs of its Unix-like underbelly.

In a nutshell, my computer is highly customized.

A few years back I got a second computer — a laptop — and quickly discovered that while keeping one computer tweaked to prime operation just the way I like it is kind of fun, trying to keep two computers in such a state, and relatively synchronized, is a frustrating exercise in futility.

I also know a good bit of web coding. As I’ve been working with WordPress for a couple years now, I’ve come across a number of good plugins and expansions along the way. Beyond issues involved with installing them, (which is admittedly pretty easy, usually) over time I have to keep up with updates to these — not to mention updates to WordPress itself. From time to time I even delve into the plugin files myself and make improvements….

And I want to put in a second blog? Am I nuts??? Thinking of what a pain it would be to maintain two copies of WordPress, I started looking into the various multi-blog solutions people have come up with. Most of them involve a lot of weird modifications to several files and basically comprise major modifications to large swaths of the WordPress code that are fundamentally incompatible with the regular version.

I am a great fan of what I consider “elegant” coding, which means that the designer does his job with the simplest and most straightforward methodology possible. And I found a very elegant solution to the “multiple blog on one install” question. Allan Mertner came up with something that blew me away with its simplicity and power.

WordPress holds all of its data in a MySQL database, and there is a single file called wp-config.php that holds the database login information. Allen looked at this and realized that if you can change that one file, you can completely replace the blog. With this key realization he came up with a cunningly straightforward multi-blog system:

  1. Replace the standard wp-config.php file with a new version that calls a different configuration set depending on what directory it’s in.
  2. Set up symbolic links that serve as “virtual directories” that all point to the WordPress directory.

Using the example of this site, I have an install of WordPress in my /blog/ directory, and a symbolic link called “nerdaphernalia” (that’s right, you’re soaking in it!) that points to /blog/. The modified wp-config file points to either the blog or nerdaphernalia config file, depending on which of those two directories it thinks it’s in.

So other than a happy user, where do I come in in all this? Well, I made a number of improvements. First, Allan’s system was great, but it required us to install various files in and around the core WordPress files, which for me at least defeats part of the purpose of using a multiblog system in the first place. I’m trying to make updates easier, remember? Updating WordPress generally involves deleting everything but the wp-config.php file and the wp-content folder, and then dropping in the new versions of everything else; but if there are important but non-standard files strewn about, I can’t just do that. I have to remember to go through and preserve those files, and then replace them when they’re done. Add in a few plugins that work the same way, and we have a real hassle.

So first off, I tucked all the files, except for the one modified wp-config.php, into a folder in a safe place. Next I set it up so that the only files that need to be modified by the user are the wp-config.php itself (with settings relating to the blog directories) and the individual wp-config-blogname files for each blog. I streamlined the wp-config file quite a bit, leaving a bare minumum of code in the file that people have to tinker with, and dumping most of it into a file that nobody should have to modify. Toss in some minor fixes, and we are left with a easy but powerful system for running virtually any number of blogs off a single install of WordPress.

I’ve blathered on long enough. Here is the download, including all the files you need (except WordPress itself), and a full set of instructions.

Please Note:

I’ve spent a lot of time working on this system, making it as solid and easy-to-use as possible. If you would like to contribute something to support this site, it is appreciated.





Good luck, enjoy, and I hope people find it useful.

This entry was posted in Webcraft and tagged . Bookmark the permalink.

117 Responses to echo “Hello Again, World!”;

  1. Pingback: links for 2007-10-29 | hansi.unblogged

  2. Pingback: David’s Technical Musings » Blog Archive » Multi-Blogging Update

  3. David Potter says:

    I decided that my changes were big enough that I should have called my solution something else – I shouldn’t have called it MultiBlog2. I’ve now renamed mine as DRP-Multi-Blog.

    I’ve also implemented a plugin so that you can display the list of virtual sites using a keyword in post or page content, e.g. [virtual_sites_list]. The plugin supports other keywords as well. Check it out at http://dpotter.net/Technical/index.php/2007/10/29/multi....

    I look forward to seeing your next version.

    Thanks,
    David

  4. Wolf Leonard says:

    Subj: Multiblog : 2nd WP blog does not install

    I’ve tried to install two blogs sharing one database follow Stephen’s instructions in multiblog-readme.txt, amplified by instructions from Allen Gurrea

    My primary/1st blog located at public_html/cat installed fine.

    The 2nd_blog does not install.

    I can see my symlink-created-2nd_blog name (“dog” using Allen’s vernacular) in my root directory, but WP does not install using rentor2owner.com/dog/wp-admin/install.php; instead it returns a “404-no file found” like it’s not seeing the file located at rentor2owner.com/cat/wp-admin/install.php

    I assume I’m not interpreting something correctly in the instructions, and was hoping someone who had experienced a similar setup problem might set me straight.

    I know the bare minimum about pHp and virtual links, but know a space in the wrong place in a pHp script can be a show stopper.

    TIA

  5. Justin Adie says:

    I’ve just finished a first public release of a new abstraction layer enabling WP users to make use of other PDO supported databses, including SQLite (rathercurious.net).

    It seems to me that a SQLite solution would be a perfect adjunct to this multiblog solution. the core of the blog (database) is then kept complete discreet.

    My solution currently standardises on a preset name and location but this could be (very – [2 lines]) easily adapted for this solution.

    in response to the multiple questions about template differentiation: i suggest that the new version of wp-config set a database variable ($wpdb->multiblogNumber) based on the request. This can then be easily inserted into the template files (such as header) to create a conditional. yes – it’s playing with actual code but not in a difficult manner.

    Justin

  6. Strider says:

    Wolf —

    “[I]nstead it returns a ‘404-no file found’ like it?s not seeing the file located at rentor2owner.com/cat/wp-admin/install.php”

    I believe what it’s not finding is rentor2owner.com/cat/

    There’s not much more I can check without access to your server, nor am I inclined to troubleshoot symlinks. My primary suggestion is to ask your hosting provider to look at the symbolic link for you and confirm that it’s working.

    You might try looking at it via FTP as well. Some FTP programs have a setting to “resolve symlinks”, meaning that it treats symlinks as folders. See if the FTP program sees dog as a file or a folder.

    Again, your host company is probably your best bet.

  7. Strider says:

    Justin —

    To distinguish between users, there’s no need for a new variable — just call the existing get_virtual_user() function. :)

  8. Strider says:

    By the way — for anybody waiting on the new version — I had it ready for release, but am still checking a potentially serious security hole.

    In my attempts to make v2.0 almost entirely configuration-free, I’ve opened it up to the possibility of hackers hosting their blogs on your server. Oops.

    Still checking it out….

  9. Pingback: Michas Weblog » Blog Archive » How to configure a multiblog wordpress on a debian box

  10. chango says:

    hello stephen, thanks for your great work here I’ve already put it to great use. I also have a need to display content from multiple blogs on a single page and noticed you are working on a release to do just this.

    I haven’t quite figured out the details, but am experimenting with rewriting the $wpdb table names with the correct prefix for the blog I am trying to query at that moment, retrieving the original query string, and then re-calling query_posts with it. I was wondering if you were doing something similar or found a more elegant solution?

    Thanks, looking forward to your next release!

  11. Strider says:

    I’ve been trying to get a list of pages that combines the pages of multiple blogs. WordPress appears to cache $wpdb in some way I can’t figure out, so no luck so far. It sounds as though what you’re trying is very similar, so let me know if you figure it out.

  12. Wolf Leonard says:

    Stephen : Thanks for your comments in #91 to my scenario in #89. We were both right.

    In synch with your advice, I pursued the symlink scenario with HostGator and the great guys there worked overtime to figure out that Allen Gurrea’s symlink instruction wasn’t quite right, at least on their server.

    I was on target with the thought that something minor such as a missing space or something-or-other could make all the difference in the world. For my situation, it was a missing forward slash.

    Allen’s pHp symlink script “home/user/public_html/cat” didn’t work for me until we added a forward slash upfront to make it “/home/user/public_html/cat”.

    Something just that simple ripped more time out of my hide than I want to think about, but it appears to have resolved the issue. So everything looks good and I’m moving forward.

    Thanks for your innovative work and the opportunity to post here.

  13. chango says:

    Hi Stephen,

    In my I need to display the most recent post from one blog, and then the last 5 posts from two other blogs, and this code seems to do the trick. I do this for each blog I am pulling from:

    //map the wpdb table names with the new prefix

    $blog_prefix = 'bob_';
    global $wpdb;
    $wpdb->prefix = $blog_prefix;
    $wpdb->posts = $wpdb->prefix . 'posts';
    $wpdb->users = $wpdb->prefix . 'users';
    $wpdb->categories = $wpdb->prefix . 'categories';
    $wpdb->post2cat = $wpdb->prefix . 'post2cat';
    $wpdb->comments = $wpdb->prefix . 'comments';
    $wpdb->link2cat = $wpdb->prefix . 'link2cat';
    $wpdb->links = $wpdb->prefix . 'links';
    $wpdb->options = $wpdb->prefix . 'options';
    $wpdb->postmeta = $wpdb->prefix . 'postmeta';
    $wpdb->usermeta = $wpdb->prefix . 'usermeta';

    //reload the query object with posts from new tables
    query_posts('showposts=5');

    //Permalinks and other post-related URLs are prepended with the value of the ‘home’ option
    //so we need to override this with the new proper value for the blog we’re pulling from
    $old_option = get_option('home');
    wp_cache_set('home', 'http://www.mysite.com/bob/', 'options');

    loop over posts…

    //Restore the original ‘home’ option so any remaining links render correctly
    wp_cache_set('home', $old_option, 'options');

  14. Strider says:

    Chango —

    Your code is _very_ similar to what I was trying to make work. :)

    It appears that the wp_cache_set() function is what I was missing. I would change the prefix and the $wpdb elements I needed, but returned the first blog’s data twice. I’ll definitely check this out. Thanks!

  15. Strider says:

    New and improved! This page now includes a Tip Jar!

    Well, okay. New and improved for me. I can’t give you guys _all_ the goodies. :)

    Version 2.0 should be up tomorrow. Just some final touches, packaging, and upload.

  16. Strider says:

    VERSION 2.0!!!!!

    This system now has its own page, rather than being a simple blog entry. As such, comments are closed here. Please leave new comments on the new page.

    The new version has _significantly_ improved ease-of-setup, plus working domains and subdomains, new functions for your themes, and a VUSER constant that you can use to specify the current blog (great for customizing themes!)

    Check it out! :)

  17. Pingback: Multiple Wordpress blogs from 1 instance / 1 wordpress folder to maintain | Woody Hayday | Blog

Comments are closed.