Multi-site setup recommendations

A.D
A.D
Vote:
 

Hello,

Just looking for some recommendations on structuring a multi-site solution. I'd like to have a single codebase, database etc, but in this case the setup is for a collection of small sites that may have unique models, viewmodels, controllers, views, layouts etc. However, these sites will share some common blocks.

I've explored the use of Areas within the MVC Alloy templates, which seems to work (see This discussion). Not sure the best way to handle some of the business logic - for example the creation of unique layout models for the different viewmodels.

Using Alloy for testing, I can do something like this - in PageContextActionFilter

public void OnResultExecuting(ResultExecutingContext filterContext)
    {
      var viewModel = filterContext.Controller.ViewData.Model;

      if (viewModel is IPageViewModel)
      {
             // create layout
             // get section 
      }
      else if(viewModel is SomeOtherViewModel)
      {
            // create layout specific to this viewmodel
      }
      
      // etc
}

Or maybe I could add a new separate filter for each view model instead?

Thoughts?

Thanks,

#115761
Jan 19, 2015 2:44
Vote:
 

Hi,

If you want so big difference between each site, what makes you want to go with a Multi Site setup instead of separate instances and code bases?

Otherwise here are some spontaneous ideas I have to get be able to have different setup on different sites.

Separate views

Display Channels

Have one Display Channel for each site, and use Tags to determine which View should be used for each site by registering Template Models or use Template Descriptors.

Note the currently you can't work that well with multiple tags and say that the tag "Site1" and "Sidebar" should both be added.

Separate View folders

You can register separate View Paths as mentioned in the discussion you refer to.

I have not tried out "Areas" but that might work for your favour but a quick guess is that it might be overkill since you also want separated logic.

Separate logic

Controllers and Base Classes

I would recommend that you use the same Controllers for all sites as much as possible and inside them try to pin point the logic that should be unique for each site.

Try to use the same Content Types on all sites. For example for news articles, contact information.

If that is not possible, use base classes such as "ArticlePageBase" that is inherited by Site1ArticlePage and Site2ArticlePage and create a Controller based on the base class.

Inside the controller, you can try to resolve which logic you would like to use. For example all pages should have a News Article listing, but the listing of News Articles should be different. Try to make the "Fetch News Articles" possible to switch instead of having two completely different controllers.

Use logic in Blocks

You could use different blocks that inherits an Interface or base class depending on which functionality you would like to tweak and add them to your site specific start page.

public interface IMyLogic
{
    void DoSomething();
}

public class MyLogicBlock : BlockData, IMyLogic
{
    public void DoSomething()
    {
        ...
    }
}

Then you can simply find your unique logic by loading your Start Page and try to find the block implementing your interface:

var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

foreach (ContentAreaItem item in startPage.MyContentArea.FilteredItems)
{
    var myLogic = contentLoader.Get<IContent>(item.ContentLink) as IMyLogic;
    if(myLogic != null)
    {
        myLogic.DoSomething();
    }

}

Your block can also have properties that helps you, your administrator or editor to add variable information, such as e-mail receipients if your logic should send e-mails.

See some more on this approch on my blog.

ServiceLocator by site

One idea I've had is to be able to register services and find them using tags. This is a very basic implementation of my idea.

You could have a Tag on each Service Implementation and try to determine

public interface IMyService
{
    string Tag { get; }
    string GetSomething();
}

public class MyServiceA : IMyService
{
    public string Tag { get { return "Site1"; } }
    public string GetSomething()
    {
        return "this is site 1";
    }
}

public class MyServiceB : IMyService
{
    public string Tag { get { return "Site2"; } }
    public string GetSomething()
    {
        return "this is site 2";
    }
}

And where you need it:

string currentTag = "Site1"; // this should come from something that determines which site you are on

IMyService service = ServiceLocator.Current.GetAllInstances<IMyService>().Where(s => s.Tag == currentTag);

string theResult = service.GetSomething();

Feature switching

Based on different rules, you could create simple Feature Switches. For example determine whether a property should be visible based on some logic (determine which site you are on)

[EditorDescriptorRegistration(TargetType = typeof(string), EditorDescriptorBehavior = EditorDescriptorBehavior.ExtendBase)]
public class VisibleForAlf : EditorDescriptor
{
    public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
    {
        base.ModifyMetadata(metadata, attributes);

        if (HttpContext.Current.User.Identity.Name.ToLower().Contains("alf") == false)
        {
            metadata.ShowForEdit = false;
        }
    }
}

and on your Content Type something like

[Display(
    GroupName = SystemTabNames.Content,
    Order = 310)]
[CultureSpecific]
[EditorDescriptor(EditorDescriptorType = typeof(VisibleForAlf))]
public virtual string MyString { get; set; }
#115764
Jan 19, 2015 9:27
A.D
Vote:
 

Thanks Alf,

I guess for the most part we expect the sites to be very similar, so we're keen to explore multi site functionality. Also, even if a site is quite different, it will probably still use the same basic blocks. These sites tend to be very small and simple as well - creating and maintaining individual databases and other infrastructure tends to be a fair bit of work in our case and seems unnecessary for such small sites.

I'll test a few of these ideas out,

Cheers

#115824
Jan 20, 2015 5:21
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.