The SubdomainModule internally redirects specific urls to specific portions of Community Server; it can also intercept links before they are rendered and change them to appear to be within the subdomain url used to access the page. The net effect is that a portion of Community Server can be isolated from the entire community and appear to be a standalone application while unaffecting the rest of the community.

For example, normally blogs are stored under the blogs/(blog) directory, where (blog) is the blog name. To access a blog named "personal" you would normally use http://server.com/blogs/personal. With the SubdomainModule class you could have a subdomain called "personal" that points to this url and access it with the following url, http://personal.server.com.

Usage

Three files are touched to use the SubdomainModule class.

  1. Edit your application's web.config file and add the following entry to the top of your <httpModules> section.

    <add name="SubdomainModule" type="TimothyHumphrey.CommunityServer.SubdomainModule, TimothyHumphrey.CommunityServer" />

    It is important that this line be at the top, or at the very least above the CommunityServer entry, so that it can take affect before Community Server. Your <httpModules> section should look similar to the following when done.

    <httpModules>
      <add name="SubdomainModule" type="TimothyHumphrey.CommunityServer.SubdomainModule, TimothyHumphrey.CommunityServer" />
      <add name="CommunityServer" type="CommunityServer.CSHttpModule, CommunityServer.Components" />
      ...
    </httpModules>

  2. SiteUrls.config is where you specify the subdomain redirections. The following sample illustrates subdomain redirection.

    <subdomains>
      <subdomain domain="blog.timothyhumphrey.name" path="$weblogs/blog" />
      <subdomain domain="(.*)\.timothyhumphrey\.name" path="$weblogs/$1" isPattern="true" />
      <subdomain domain="localhost/csweb" path="${reader}" />
    </subdomains>

    Each <subdomain> entry defines a different subdomain redirection; there is no limit to how many there can be. Each entry is compared against the incoming url and if a match is found processing is done. Specifically, the domain attribute of each entry is compared against the incoming url. For example, given the following url, blog.timothyhumphrey.name/archive/category/1003.aspx, the first <subdomain> entry would match it. When a match is found the path attribute of the <subdomain> entry specifies where in the Community Server url hierarchy the request should go. In this case it would go to the location where blogs are kept and then the blog named "blog".

    The SubdomainModule uses variables to refer to locations defined within the <locations> node of the SiteUrls.config file. Variables begin with a dollar sign $ and are followed by a name which should match a <location> node. The name part of a variable may be surrounded by braces { }, as in the third <subdomain> entry in the sample, to separate the variable name from following content.

    In the second example the isPattern attribute is used to indicate that the entry uses regular expressions. It is beyond the scope of this document to explain regular expressions, but standard .NET regular expressions are used and thus documentation on them are applicable here as well. The second example will match all subdomains of the timothyhumphrey.name domain and redirect them to the blog of that name. The specific subdomain used is saved in the domain attribute and referenced in the path attribute, the $1 variable. Numbered variables actually follow the scheme of .NET substitution patterns, in fact with the isPattern attribute applied the path attribute is treated as a substitution pattern and all .NET substitution pattern metacharacters may be used. The only difference in this is that named variables matching Community Server <location> entries are substituted before any named pattern matches. Note that <subdomain> entries are processed in the order they are listed so it is usually best to place entries with the isPattern applied after any entries that might match them.

    Notice that in the third example entry the server name, localhost, is followed by a path. This indicates that the subdomain to be matched need not technically be a subdomain, any part of the url up to any query string is checked. However, any subdomain specified should at least include the base url of the location the application is stored. For instance, using the same <subdomain> entry of the sample, the domain attribute must be at least localhost/csweb, and not simply localhost, if the Community Server application is stored under the csweb directory. This normally need not be remembered, but it bears mentioning.

    <location> entries in SiteUrls.config are considered special and urls that begin with their path attribute will not be redirected; except if the path is solely the "/" character. This allows urls that wouldn't work if redirected to work. For instance the control panel urls should not be redirected to a blog, forum, etc. Version 1.3 of the SubdomainModule required either an exclude or subdomainExclude attribute set to true to achieve this effect. In addition, similar to <subdomain> nodes, the isPattern attribute may be specified and set to true to target a broad range of urls to ignore.

    To prevent redirection of some commonly used files you can include the following <location> entries:

    <location name="services" path="/.+?\.(axd|ashx)" isPattern="true" />
    <location name="tiny_mce" path="/tiny_mce" />
    <location name="login" path="/login.aspx" />
    <location name="logout" path="/logout.aspx" />

  3. The communityserver.config file is optionally modified, but recommended. An entry to this file is made so that the links Community Server renders are altered to appear to come from the subdomain. For instance, a link to a blog category might normally appear as /blogs/blog/archive/category/1003.aspx but will get altered to be /archive/category/1003.aspx.

    The entry that is made is a new SiteUrlsDataProvider. It is easiest to search for the occurrence of this phrase in this file to find the entry containing it. You will have to comment out the existing entry provided by Community Server and replace it with the one provided by TimothyHumphrey.CommunityServer, like so:

    <!--
    <add
      name = "SiteUrlsDataProvider"
      type = "CommunityServer.Components.SiteUrlsData, CommunityServer.Components"
      path = "SiteUrls.config"
    />
    -->
    <add
      name = "SiteUrlsDataProvider"
      type = "TimothyHumphrey.CommunityServer.SiteUrlsData, TimothyHumphrey.CommunityServer"
      path = "SiteUrls.config"
    />

Remarks

As of version 2.0 the SubdomainModule monitors the SiteUrls.config file for changes and updates itself accordingly if full trust is enabled for the web site. To force an update however go to ~/subdomains.axd, where the ~ character represents the root of your Community Server instance.

To prevent blog comments from being redirected to their true locations in Community Server 2007 you can use the GoToModifiedUrlAction class from TimothyHumphrey.CommunityServer. It is derived from the native Community Server class and is used in exactly the same way, thus you need only change its tag prefix in your .aspx files to "th". For example:

<SuccessActions>
  <th:GoToModifiedUrlAction runat="server" QueryStringModification="CommentPosted=true" TargetLocationModification="commentmessage" />
</SuccessActions>