Overriding content based on the host header

Topics: Customizing Orchard
Jun 3, 2011 at 3:06 PM

We recently went through the process of redesigning our corporate website in Orchard. However, today I found out that we have a small consulting company in Canada that wants to use their existing DNS name and have it point to our site. Having multiple host-headers for a single site is easy. Unfortunately, the consulting company is also asking for customizations for a few of the pages. For example

  • Homepage - will have a similar layout to the current homepage with the rotating image in the center of the screen with different content.
  • Header - Will have a different image and logo
  • Navigation - Will be customized
  • About Page - Customized, fields added/removed
  • Markets - Link to content of primary site
  • Services - Link to content of primary site
  • Locations -  Link to content on primary site
  • Contact Us - Custom page for consulting firm
  • Footer - different content.

I am not sure how to pull this off in orchard. I could use multi-tenancy but that requires a separate database to be used for each domain name and since most of the content will be the same between the two sites that seems like the wrong approach.

Anyone have any ideas on how to pull this off without putting hacks everywhere in the code?

Jun 3, 2011 at 3:54 PM

I've been thinking about this situation, since I'm building a site that will eventually run on multiple domains with the same kind of customisation story. Sometimes different logos or stylesheets and other template tweaks will be needed, and in most cases the sites will display different content but will still need to pool users and content all from the same database.

What I'm thinking about is some kind of "Multiple Domain" module that will enable this. Actually, customising the theme for each domain is already pretty easy. You can implement a theme selector which is an existing interface in Orchard, and pick the theme based on the domain. Each theme can inherit from the same base theme, and then you can override whatever templates you need specific to that site.

Displaying different content might be another matter entirely; since in RoutePart the URLs are hard-wired to the RoutePart.Path field, via RoutablePathConstraint and ItemController, I'm not sure if there's any way around it without just replacing the whole routing mechanism. But, since I'm already doing that (for other purposes), it would be feasible to add multi-domain support into my routing.

Another way to look at it might be as a kind of Versioning or Localization that's based on domain instead of other attributes. Haven't looked into them yet to see if it's possible to hook in in any way.

Anyway; it's not something I can get stuck into for another few weeks, but it's definitely something I'll be needing so I'll try and help out if you're having a go!

Jun 3, 2011 at 4:08 PM

I would suggest to go with multi-tenancy. And duplicate the content whenever needed. You can even setup one website, copy its db, then create the new tenant and update the corresponding sections. Each tenant can also have its own theme, and here you can use child themes, to share most assets between websites.

Jun 3, 2011 at 6:28 PM

The "multiple domain module" is exactly what I am after. I also like the idea of modifying the theme selector. If each domain has its own theme then I can even use Url Alternates for overriding some of the pages.

My only reservation is that I would probably have to modify the Orchard code in get this working. Up to this point, we have done a good job of keeping our code isolated from the core product.

Jun 3, 2011 at 8:04 PM

You can just implement IThemeSelector to add your own theme selection logic - no modification of Orchard needed. For per-domain content variations it's more involved; but you still shouldn't have to actually modify any of Orchard. You can replace anything in Orchard using the [OrchardSuppressDependency] attribute and replace your own implementation - any interface that inherits from IDependency or ISingletonDependency can be replaced this way by your modules.