Virtual communities through Community Server Groups

If you're a little bit familiar with Community Server 2008 and newer versions you might be wandering is it possible to define several CS Groups and give each of them separate URL such as http://en.company.com or http://de.company.com.

Now let's be clear about Group and Hub – since name Group was confusing, because there are groups of blogs or media galleries as well, you can also think about groups of users, so Telligent decided to introduce this new term Hub. And under the cover CS refer to this entity only as Hub. So am I.

Since each hub has almost everything you need for mini community (blog, forum, media gallery, etc.) then it could be great to have it exactly like mini-communities with different URLs and same CS database. This could be useful for intranet/internet community versions, multi-language site, etc.

The short answer – yes, it's possible and this functionality supported with Community Server 2008.5 together with our product Upupo Media Server.

Quick steps:

  1. Install Upupo Media Server
  2. Get SiteUrls_Override.config (attached), Search and Replace 'App=main' with 'App=Your_Hub_Name'
  3. Optional. Your new registered site users will be added to your group automatically (group auto join module).

Edit (create) CommunityServer_override.config, and add module for hub

<Override mode="add" where="end" xpath="/CommunityServer/CSModules" >

<add name = "AutoJoinHubModule" type = "Upupo.Hubs.Components.Modules.AutoJoinHub, Upupo.Components" />

</Override>

  1. Also append this at the end of your CommunityServer_override.config

<Override xpath="/CommunityServer/Hub" mode="new" name="defaultApplicationKey" value="Your_Hub_Name" />

That's it now when you open your site http://youhost.com/ you'll see first hub page, when you navigate to /blogs – hub blogs, /forums – group forum, etc.

Though your member-related pages will work as usual

Now the long answer.

The point where you start – take a look at SitUrls.config and SiteUrls_override.config and try to find a way to override root (common) nodes and set it to group(hub) urls. What if we replace all location with urls pointed to some specific group(hub)?

Let's see, first we define location

<location name="common" path="/" themeDir="common" >

then some url

<url name="home" path="" pattern="default.aspx" physicalPath="##hubthemeDir##" vanity="{2}" page="home.aspx" indexable="firstpageonly" />

Well, the problem is that there is no place in url format where we could set a hub name.

But <location> is being processed because there is class CSLocation in CS. What if we create our custom location where we can process some custom parameter (hub name) using url format.

Then we could use urls like this, where 'MiniSite' is a hub name:

<url name="home" path="" pattern="default.aspx" physicalPath="##hubthemeDir##" vanity="{2?App=MiniSite}" page="home.aspx" indexable="firstpageonly" />

So our custom location provider for urls could be like this:

public class RootHubLocation : CSLocation

{

public RootHubLocation(string path, string physicalPath, string themeDirectory, bool exclude, string applicationType)

: base(path, physicalPath, themeDirectory, exclude, applicationType)

{

}

 

public override string GetReWrittenUrl(ReWrittenUrl url, string path, string queryString)

{

// string app = "main";

string app = this.NamedValue(url, "app");

if (string.IsNullOrEmpty(app))

return base.GetReWrittenUrl(url, path, queryString);

else

{

 

CSContext csContext = CSContext.Current;

ThemePage tp = new ThemePage();

 

HubsContext context = ((HubsContext)csContext.ApplicationContexts[CommunityServer.Components.ApplicationType.Hub]);

 

if (string.IsNullOrEmpty(context.HubTheme))

context.HubTheme = CommunityServer.Hubs.Components.Hubs.GetHub(app, true, true).Theme;

if (context.HubTheme != null) tp.Name = context.HubTheme;

return url.GetReWrittenUrl(path, queryString, tp);

}

}

 

private Regex _regex = null;

 

public string NamedValue(ReWrittenUrl url, string name)

{

string pat = @"([^\r\n]*\?App=)(?<app>[\w\.-]+)";

_regex = new Regex(pat, RegexOptions.IgnoreCase | RegexOptions.Compiled);

 

string res = _regex.Match(url.Path).Groups[name].Value;

return res;

}

 

Now you'll need to create your SiteUrls_override.config (take a look at the example attached) and replace App=main to App=Some_Hub_Name

As you can see you can add some specific hub sub-apps from other hubs (with different ?App=Another_Hub_Name)

So, we can process our urls in a specific way and now every single url will route user to hub and it's sub-applications.

But what about new registered users on our site? They can't add any content inside hub (and all our community is just one hub now) until user is a member of this hub.

So let's make any user who registered auto join our main hub. For this we need to create module, something like this:

 

/// <summary>

/// CSModule to auto create a user gallery when a user registers.

/// </summary>

public class AutoJoinHub : ICSModule

{

public void Init(CSApplication csa, XmlNode node)

{

csa.PostUserUpdate += csa_PostUserUpdate;

}

 

private static void csa_PostUserUpdate(User user, CSEventArgs e)

{

if (user == null || e.State != ObjectState.Create) return;

HubsContext hubcontext = ((HubsContext)CSContext.Current.ApplicationContexts[CommunityServer.Components.ApplicationType.Hub]);

Hub hub = hubcontext.CurrentHub;

 

if ( hub == null || (!hub.IsPublic && !hub.IsCommunityAggregated) || hub.IsMember(user, SectionMembershipType.Manager | SectionMembershipType.Member | SectionMembershipType.Owner))

return;

 

if (hub.MembershipIsOpen)

{

// membership is open so the user can be added as a member immediately

 

SectionMembership sm = new SectionMembership();

sm.ApplicationType = ApplicationType.Hub;

sm.UserID = user.UserID;

sm.SectionID = hub.SectionID;

sm.MembershipType = SectionMembershipType.Member;

sm.DateAdded = DateTime.Now;

 

SectionMemberships.Add(sm);

}

 

}

}

 

Basically that's it, just don't forget to add at the end of your CommunityServer_override.config

<Override xpath="/CommunityServer/Hub" mode="new" name="defaultApplicationKey" value="Your_Hub_Name" />

Now you can create some iis instance, add custom dns header name to it and assign to CS with changes we just described.

Next mini-community could another iis instance configured the same way, but with different "App=You_Hub_Name2" in config file.

Happy hacking!

 


Posted Feb 06 2009, 01:13 AM by Dmitry

Comments

dileep wrote re: Virtual communities through Community Server Groups
on 10-16-2009 7:34 PM

Hi,

I'm working on a project something similor.Do we have to configure different config file for each domain/group? if so how we can put all of them in one root folder?

How the URL look like?en.company.com/blogs/default.aspx , en.company.com/forum/default.aspx  

or the en.company.com will change back to company.com/groups//en/default.aspx