Let's say you want to use a single Drupal install to run your company's primary web site and your company's blog site (multisite), but you also have different themes and navigation hierarchies for the two sites. Sure, there are some Drupal modules that may provide most of this functionality. However, you can accomplish exactly the same thing with a plain vanilla Drupal install and the Pathauto module (a module that you should really be using anyways).

Drupal's built-in multisite capabilities are great, but are not well documented and are easily misunderstood. Typically, a multisite is setup to separate data in the Drupal database for a site that is using the same Drupal code base — multiple sites with a single Drupal install to maintain. The Drupal settings configuration is modified so that the sites override certain tables. For example, both sites may use the same access tables, but override the rest of the tables.

Comments in the standard Drupal install settings.php file give an example of this:

* $db_prefix = array(
* 'default' => 'main_',
* 'users' => 'shared_',
* 'sessions' => 'shared_',
* 'role' => 'shared_',
* 'authmap' => 'shared_',
* );

This is all very useful, but there is no clear way to utilize these powerful, core multisite capabilities of Drupal to achieve a multisite that shares all database tables and also has a unique theme and specific content type associated to a secondary site. Again, a perfect example of this is a subdomain blog site accompanying a main company site: www.company.com and blogs.company.com

As an administrator of both sites it would be nice if it were possible to accomplish the following:

  1. Share the same core Drupal install - add/upgrade modules just once, instead of site by site
  2. Different themes
  3. Different front page
  4. Site specific block configuration
  5. Easily shared content across sites
  6. Domain specific content types, only published once, available via Views on all sites, only have one URL for SEO purposes
  7. Share content, specifically so that Views has access to the same content on both sites (so you may for example easily add a recent blogs block to the www front page)

One way to achieve this would be to use the very powerful Domain Access module. However, this module is one of the more complex and invasive modules; you have to really buy in, all or nothing.

So, how does one achieve a sub-domain site that is really just a landing place for a certain content type (and without any additional modules). A big part of the answer is Drupal's 'Variable overrides.' Variable overrides allow you to override configuration values that are stored in the Drupal database 'variables' table.

For example, the following entry in the in the settings.php of the blog site directory ( setup of /sites directory for multi-site) will allow you to override the site name, the theme and the default front page of the site:

$conf = array(
 'site_name' => 'CapTech Ventures Blogs',
 'theme_default' => 'blogs_captech',
 'site_frontpage' => 'blog/list',
);

Great, so this allows you to easily apply a unique look to another site hosted on a single Drupal instance and share all of your content across both sites. However, we would also like to have all the content of a particular content type, say 'blog entry', only be displayed on the blogs domain. So how could we do this?

First, use the Pathauto module (yeah, I know I said no extra modules, but this one should be part of core anyways and if you don't have it installed then you need to install it ASAP) ... anyways, use Pathauto to automate the URL alias of all blog entry content. For example:

blog/[author-name-raw]/[title-raw]

Now that you have a nice clean URL to work with and one that is unique to the 'blog entry' content type, it is time to explain how to have selected content type(s) be domain (subdomain) specific. To achieve this, we will turn to Apache mod_rewrite.

If you are using clean URLs with your Drupal install, then mod_rewrite is already enabled on your Apache install. Otherwise, you will need to check that it is enabled and enable clean URLs. Once you have ensured that it is enabled, all you have to do is modify the Drupal .htaccess to rewrite all urls specifically aliased for blog related content:

RewriteCond %{HTTP_HOST} ^www.company.com$ [NC]
RewriteRule ^blog/(.*) http://blogs.company.com/blog/$1 [QSA,R=301,L]

The RewriteCond is needed so that you don't end up in an endless loop trying to rewrite blogs subdomain requests getting rewritten to themselves. With the condition and rule above, only .../blog... requests to main www site will be redirect to the blogs subdomain.

Some nice things about this approach are:

  • Search engines will only index the rewritten url, so all blog content for www or blogs will be indexed as: blogs.company.com
  • Any links in the www site to blog content will automatically get directed to the blogs subdomain (even Drupal search results on the www site); nice! So, you can create a nice block view of recent blog entries for the www home page, and have all the links redirect to the blog site.

Tips for local development

Modify your hosts file to simulate subdomains. This will allow you to locally test your mod_rewrite conditions and rules.

Example:

127.0.0.1 local.blogs.company.com

Issues

We would like to provide search of only blog content on the blogs subdomain. We are already using the search_exclude module, but setting 'Variable overrides' has no effect. Any ideas would be appreciated.