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.

117 Comments

Pages: « 1 2 [3] 4 5 6 » Show All

  1. #41 | Posted July 12, 2007 at 6:44 am

    [...] I don’t know how to tinker with .htaccess so I just copied the suggested contents from Stephen Rider’s multiblog file and it worked! I am so thankful that my blog is back [...]

  2. #42 | Posted July 12, 2007 at 11:40 pm

    Hi,
    Thanks for visiting my blog. =)

    I made a follow up question with a problem in my blog. Although I think I have the solution, I still need your advice since my solution was just a guess. Thanks.

    Allen

  3. #43 | Posted July 13, 2007 at 11:26 pm

    Hey there, I have noticed a weird problem in my blog. Once in a while, the blog permalinks are not working correctly (redirecting to the other blog thus a dead link). I have to reset the permalink structure just to make it work again. Have you encountered this error?

    Thanks.

    Allen

  4. #44 | Posted July 14, 2007 at 10:18 am

    As stated in the readme, you’re replacing the contents of the .htaccess with something like this:

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_URI} ^/(bob|joe)/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /%1/index.php [L]
    </IfModule>
    

    The important bit is that you do NOT want to allow WordPress to overwrite this. Try changing the permissions of your .htaccess so that WordPress can NOT write to it.

    As an additional caution, I would put this replacement redirect _before_ the #WordPress markers, not within them. That way (theoretically) if WordPress does write to the file down the road, the new redirect will fire before the default WordPress one.

  5. #45 | Posted July 14, 2007 at 10:39 am

    Yes I did do that. But I guess I forgot to CHMOD .htaccess… All seems fixed now. Thank you once again for your multiblog idea. ^_^

  6. Dgold
    #46 | Posted July 22, 2007 at 3:36 pm

    This is amazing Stephen. I have been reading (and getting headaches) about every multi-blog option including MU. This was the only one that made sense to me, and actually worked when I tried it. I set up 4 new blogs tonight on 1 install of WP, with your method (and I used mo’s PHP code to make the symlinks because I didn’t know another way to do it – you could improve on the instructions in this area). Before this I already had about 5 WP’s on 5 installs.

    Some of my questions so far:

    1. If I want to move some of my old separate installs under one-roof, should I just Export from the old one, set up a multi-blog “joe” and Import there? Then I would just move the theme from the old separate wp-content, into the multi-blog “bob” wp-content folder, and select it in the “joe” admin Presentation tab? Then I would have my same old blog back, but running under the bob install, right?

    2. What happens with the different multi-blogs sharing 1 wp-content folder? If someone uses the “upload” function on any of the multi-blogs, will it store ALL the files in the “bob” wp-content folder, for all the sub-blogs?

    2.B. If I do question #1 to put an old blog under the “bob” roof, can I move any random files like photos from the old wp-content into bob’s wp-content, and the links to those JPEG’s will remain valid?

    Thank you extremely very much for this. I wish I had known this method when I started installing multiple copies of WP a couple years ago.

  7. #47 | Posted July 23, 2007 at 9:07 am

    Dgold –

    I should probably separate this instruction set into sections — How to make symbolic links/ how to convert an existing blog, etc…. On to your questions:

    1. You’re working too hard! Just point mb-config-joe.php to the existing database for Joe — assuming it’s on the same server. No import/export needed. If the path to the blog is changing, you might want to use the MySQL utility of your choice to change the path in the joe_options table. (Careful! You have to change it in two places in that table.) If you want the blog to be in the same location as before, you will have to rename the existing /joe/ folder before creating the /joe/ symbolic link to /bob/. When everything is working properly and files are copied over, you can delete the old renamed /joe/ folder.

    2. You are correct that all blogs share a wp-content folder. You can go into Options for each blog and change the upload folder to anything you want (such as /wp-content/uploads/joe/ and /wp-content/uploads/bob/).

    2.B. Yes, you have to move your Joe content into the Bob folder. If you know a bit about mod_rewrite, you can do a rewrite to keep content separate without complicating your links. For example, I use something like this in my .htaccess file:

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_URI} ^/(bob|joe)/(demos|downloads|images|archive)/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule /(.*)$ /%1/wp-content/docs/%1/%2/$1 [L]
    </IfModule>
    

    Thus /bob/images/ invisibly reroutes to /bob/wp-content/docs/bob/images/ and /joe/images/ reroutes to /joe/wp-content/docs/joe/images/, and so forth.

    I’ve figured out a few mod_rewrite tricks related to this methodology. I really should do a formal writeup some time…. :-)

  8. #48 | Posted August 2, 2007 at 1:14 am

    [...] thanks to the genius that’s found in the mind of a fellow by the name of Stephen Rider. On his blog, he describes how he was able to install one copy of wordpress and run multiple blogs using [...]

  9. #49 | Posted August 3, 2007 at 8:29 pm

    I’ve managed to set up multiple blogs with one WordPress install, thanks to your article. However, I’d like the header to be a bit different for each blog. Is there an easy way to go about doing that?

  10. #50 | Posted August 3, 2007 at 9:42 pm

    Billy — Each blog can use a different theme, so you can put whatever you want in the page headers of each theme.

  11. #51 | Posted August 3, 2007 at 10:45 pm

    ok, so if i want the blogs to use the same theme, only use different headers, i’ll need to make a copy of the theme i’m using for each blog and change the header graphics in each (copied) theme directory?

  12. #52 | Posted August 4, 2007 at 9:18 am

    I’ve got my site set with your article as a guide, which is exactly what I was looking. However, I’d like each blog to use the SAME theme, except the header needs to be different, that’s all. The styles and everything else remains the same. So, I was thinking – there should probably be a way to duplicate the header.php file for each virtual blog, modify each header.php, and have each virtual blog use the right header.php.

    The problem is when I change the header.php on the blog that has the actual wordpress files in it, the header also changes on all the virtual blogs. Isn’t there a way of making each of the virtual blogs point to a different header.php file? – something similar to:

    include (TEMPLATEPATH . ‘/header2.php’);

    Hope I’m making sense -

  13. #53 | Posted August 4, 2007 at 9:57 am

    In WordPress there’s a defined constant called ABSPATH, which is directory your current blog is in. So you could do a separate folder for each blog inside your theme folder, and then use something like:

    include (TEMPLATEPATH . '/' . ABSPATH . 'header2.php’);

    Thus the blog in /joe/ would use TEMPLATEPATH/joe/header.php

    With this method a blog at the root level would probably use the header file in the base template folder, but either way you would have to include some PHP logic to avoid a double slash (‘//’), as ABSPATH ends with a slash.

    Incidentally, if you want the sidebars to be different in each, try using Widgets instead of hacking the templates.

  14. #54 | Posted August 4, 2007 at 10:00 am

    Actually, Billy, I’m glad you asked that question. Answering you figured out something I’m going to start using myself. :)

  15. Dgold
    #55 | Posted August 4, 2007 at 11:19 am

    Thanks again for this ingenious multiblog technique. (1) Stephen, I think it would be helpful if you highlight mo’s method for making symlinks or insert it in the original post above. (2) I am following Billy’s question because I will want to do the same thing with the header too. Now, I have a new question:

    (3) I want to copy-paste my pre-customized database, into each new multiblog! Is it possible? To explain, I created a master-blog and I want all the sub-blogs to start with my identical 3 categories, 2 usernames and passwords, my custom Hello World post, my custom First Comment, my empty blogroll, and other such details that are stored in the database. I do NOT want each new multiblog to install the standard default WP Hello World post, first comment, Admin username, and randomly generated password. The reason, you can imagine, is the same as the reason for this multiblog technique: to save time and headache of repeated tasks; I don’t want to edit Hello World 20 times. I don’t want to log-in the initial random password and then change it to my admin password 20 times. I don’t want to delete “Uncategorized” and create my same 3 categories, 20 times. I don’t want to go Admin > Blogroll > Delete All, 20 times.

    I don’t know much about MySQL but I can get into PHP-MyAdmin and see my database. I want to store all my multiblogs in 1 database, and each has a different table-prefix (which can be the same as each blog’s folder, for example prefix joe_ and bob_) — I have done it for 3 blogs already using the traditional method of putting my table_prefix in wp-config and then running the Famous 5 Minute Install. Now I want to accomplish the copy-paste described above, and my novice *guess* is that I can copy the table (tables?) of the master-blog, and then paste to a new table with the new prefix… 20 times. Then, kind of reverse of the usual WP install process, I would create the wp-config that points to that database & that table, and make the matching multi-blog with symlinks. Then, again I am guessing, I would log-in to the new multiblog and it would never require the 5-Minute Install, because it is already a pre-written database, already has admin with password, thus looks like it is already installed. WP would never know that I did not run the installer individually for each blog.

    Will this work? Do you see pitfalls in my approach? Any tips, warnings, or reassurances? Most importantly: can you tell me how to copy a table in MySQL (PHP-MyAdmin), and paste the table’s contents into a new table with a new table_prefix? Is there any other unique identifier or hook for each blog, besides the table prefix, that I need to think about?

    Thanks again.

  16. #56 | Posted August 4, 2007 at 11:21 am

    Where exactly am I to place the code:

    include (TEMPLATEPATH . ‘/’ . ABSPATH . ‘header.php’); (with the opening and closing php tags on each end, right?)?

  17. #57 | Posted August 4, 2007 at 9:04 pm

    Billy — presumably, place it in your template file where you want the header to be. You’re the one who suggested the include!

    Dgold — i don’t use PHP-MyAdmin at all — it’s too clunky. I suggest finding a dedicated “real” program that runs on your computer’s OS. On my Mac I use Cocoa MySQL, but there are others.

    I don’t think you would have any problems copying the tables, but BEWARE or fields in the tables that specify directories or table prefixes. You will have to change those manually each time (though depending on the program, you might be able to do a search/replace).

    Again, there are some fields that specify the path to the blog (which will change with each) and there are fields that are named with the table prefix (“wp_” or whatever).

    As long as you’re on top of those, you should be fine just duplicating tables.

    As you’ve partially noted, this method is long overdue for a re-writeup. Busy lately, but I’ll do it one of these days.

  18. #58 | Posted August 10, 2007 at 4:03 pm

    Dgold — check out this link!

    http://wpbits.wordpress.com/2007/08/10/automating-wordp...

    It’s an article describing a way to customize WordPress installations. With this you could easily customize the first post/first comment/categories/users/etc. as you describe above.

  19. #59 | Posted August 11, 2007 at 10:51 am

    I’m *very* familiar with WordPressMU – whioch is more blog farm software, but this this looks like an excellent solution for, not people looking to admin just a few blogs of their own.

  20. #60 | Posted August 16, 2007 at 12:40 am

    I previously suggested to Billy Miles that he use the following code:

    include (TEMPLATEPATH . '/' . ABSPATH . 'header2.php’);

    This will not work, as ABSPATH is the full server path of a file — that is, the path from the root of the hard drive. Not sure how to make it work with the files as-is, actually. It will probably require another constant being defined in the wp-config.php file.

    Sorry ’bout that!

    I’m working on a significant update to this method, that will hopefully resolve some of these issues.

Pages: « 1 2 [3] 4 5 6 » Show All