People occasionally wonder whether WordPress makes it possible to have two separate blogs on a single site. Perhaps you have two different authors, and want each author’s posts displayed separately. Or perhaps you want to blog about two different topics and keep them separate.
The short answer is “No, WordPress doesn’t let you do this”.
The longer answer is “Yes, but it takes some work”.
Let’s say that we want to do this for a website about Chalk and Cheese. Here’s what we’re aiming for in terms of functionality: The site should have two blogs, one displaying only Chalk posts, and the other displaying only Cheese posts. On each blog page, archive links should lead to archives displaying only posts in the appropriate category.
Setting up Categories
First, we need to set up two categories, “Chalk” and “Cheese”. Every post should be assigned to one of these categories, depending on which blog it belongs to. I’ll assume, in what follows, that the Chalk category id is 1 and the Cheese category id is 2.
Setting up the Blog Home Pages
Next, we’ll set up the home pages for each blog. First, make a copy of your index.php theme file, saving it as “cheese.php”. (While you’re at it, make two more copies called ”category.php” and “archive.php”; we’ll need these later.) Make this file a template by adding the following code at the top of the file:
<?php
/*
Template Name: Cheese
*/
?>
Now, we need to exclude the Cheese posts from the Chalk home page and the Chalk posts from the Cheese home page. In the index.php theme file, directly before the loop, add <?php query_posts('cat=-2'); ?>. Then, in the cheese.php theme file, add <?php query_posts('cat=-1'); ?>.
Now, create a new Page called “Cheese”, and assign the “cheese.php” template to it.
You should now have two pages, one showing your latest Chalk posts and the other showing your latest Cheese posts.
Archive Links
Unfortunately, if you click one of your archive links you’ll see that your archives contain both Chalk and Cheese posts. This isn’t what we want; we want to have two separate archives.
To make this work, we’re going to get archive links on the Cheese pages to pass a variable identifying it as a Cheese link. Our archive pages can then check for this variable, and show either only Chalk posts or only Cheese posts as appropriate.
To do this, add this code to your functions.php theme file:
add_filter('month_link', 'cheesy_month_links');
function cheesy_month_links($month_link) {
if (is_page('Cheese') || $_GET['cheesy'] == 1) {
$month_link .= "?cheesy=1";
}
return $month_link;
}
Whenever WP generates a list of monthly archive links on a ‘cheesy’ page, this code interrupts and adds “?cheesy=1″ to the end of each one.
Similar code using the page_link, post_link, term_link, day_link, year_link, author_link, and tag_link hooks can be added to make sure that all links on cheesy pages pass this variable through the url.
Now would be a good time to replace ”<?php the_permalink(); ?>” with ”<?php the_permalink(); ?>?cheesy=1″ in your cheese.php template so that links to Cheese posts pass this variable too.
Archives
Having passed this variable through the url, we can now get our archive pages to check for it and filter posts accordingly.
Add the following code directly before the loop in your archive.php theme file:
<?php
if ($_GET['cheesy'] == 1) {
query_posts($query_string . '&cat=-1');
} else {
query_posts($query_string . '&cat=-2');
}
?>
The category archives need to be handled slightly differently. Open your category.php theme file and add the following code just before the loop:
<?php
$cats[] = get_query_var('cat');
if ($_GET['cheesy'] == 1) {
$cats[] = 2;
} else {
$cats[] = 1;
}
query_posts(array('category__and' => $cats));
?>
You should now have two separate blogs, with separate archives.
Menu Highlighting
If your site’s menu highlights the current page parent, then you’ll have noticed a problem: when you’re on a cheesy page other than Cheese itself, the Cheese link in your menu won’t be highlighted but the Chalk page will.
To fix this, on cheesy pages we’ll capture the menu code as it’s generated and change the highlighting. To do this, we need the page id of the Cheese page; I’ll assume that it’s 3. Add this code to your functions.php theme file:
add_filter('wp_list_pages', 'cheesy_highlight');
function cheesy_highlight($output) {
if ($_GET['cheesy']) {
$output = str_replace(" current_page_parent", "", $output);
$output = str_replace("page-item-3", "page-item-3 current_page_item", $output);
}
return $output;
}
That should ensure that the corrrect page is highlighted.
So does WordPress make it possible to have two separate blogs on a single site? It isn’t easy, but with WordPress, pretty much anything is possible.
November 3rd, 2009 at 12:27 pm
Hi
Just what was looking for.
What if I use a static page as my welcome page? Does the same code apply?
Is it right if my index.php looks like this:
many thanks
schalk
November 3rd, 2009 at 12:43 pm
Yes, you should be able to use the same approach irrespective of whether your blog page is your front page.
November 3rd, 2009 at 2:04 pm
Hi Tim
Thanks for the quick response. Unfortunately I don’t get this right. I did as you said to just before Archive. However all new posts still go to my original plog post, even though I post it to the “mill” category.
If you have a minute, please have a look.
Much appreciated.
http://www.beaumont.co.za
My WineBlog category is ID 4
My Mill Category is ID 6
My “extra blog page” or rather mill.php looks like this:
November 4th, 2009 at 1:18 pm
Hi Tim
I think I have it solved, must do some more testing after uploading more posts, but I inserted the code directly before the Loop. It only worked when i added it underneath the get_header
thanks