Sitecore is a multisite system, meaning that you can administer multiple websites in the same Sitecore, and that these websites can share common data (like users, templates, masters, items, etc.).
Each website in Sitecore will run in its own context, and this context is managed from the web.config. The context is set up by defining a Site. Each context has its own site definition, and it includes a “shell” site, defining the Sitecore editor context (the shell), “modules_shell” and “modules_website”, defining the context for modules running in either the Sitecore Shell or the default website.
The site called “website” defines a default web context:
<sites>
<site name="website" language="en" rootPath="/sitecore/content" startItem="/home" cacheHtml="false" virtualFolder="/" physicalFolder="/" database="web" domain="extranet" allowDebug="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />
</sites>
The attributes to pay attention to (regarding multisite solutions) are the following:
- rootPath: The path to the root of the website. This is not the path to the first page of the website, but simply defines where Sitecore will look for items.
- startItem: The path relative to the rootPath where the first page (home page) of the website is found.
When defining multiple websites in your Sitecore you take advantage of these 2 attributes, along with a new attribute called “hostName“, which I will explain later. First I will define my multisite structure:
In my multisite solution I will have a shared “Settings” folder, and 2 websites, each with their own “Settings” folder. This is my imaginary Sitecore tree:
/sitecore/
/content/
/website1/
/home/
/subitems…/
/settings/
/website2/
/home/
/subitems…/
/settings/
/settings/
In my web.config I will need to set up 2 new “website” sites. I add these above the existing “website” site (or I can delete the old “website” and replace it with my 2 new ones). Never add your website sites to the top of the list, as Sitecore finds the current context based on first match rather than best match:
<site hostName="site1.mysite.com" name="website_1" language="en" rootPath="/sitecore/content/website1" startItem="/home" cacheHtml="false" virtualFolder="/" physicalFolder="/" database="web" domain="extranet" allowDebug="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />
<site hostName="site2.mysite.com" name="website_2" language="en" rootPath="/sitecore/content/website2" startItem="/home" cacheHtml="false" virtualFolder="/" physicalFolder="/" database="web" domain="extranet" allowDebug="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />
Please notice the hostName attribute. This attribute defines on which URL your site will be hit, and which context sitecore will create when calling this url. The hostName is important in a multisite environment as this is the way Sitecore will determine which item to render.
In my example, the url http://site1.mysite.com/ hits the item at /sitecore/content/website1/home, because I have defined that the rootPath and startItem for the hostName site1.mysite.com is on that path.
Sitecore provides functions to get the root path and start item for the current context. So when working with multisite solutions you should always get a path relative to the Sitecore.Context.Site settings:
Response.Write("Current site: " + Sitecore.Context.Site.Name + "<br/>");
Response.Write("Database: " + Sitecore.Context.Site.Database.Name + "<br/>");
Response.Write("Content start path: " + Sitecore.Context.Site.ContentStartPath + "<br/>");
Response.Write("Home node: " + Sitecore.Context.Site.StartPath + "<br/>");
Response.Write("Language: " + Sitecore.Context.Language.GetDisplayName() + "<br/>");
The code above would give me the following output for the site at site1.mysite.com:
Current site: website_1
Database: web
Content start path: /sitecore/content/website1
Home node: /sitecore/content/website1/home
Language: English : English
So, in order to get the “Settings” folder for the site at hostname site1.mysite.com, I should write the following code:
Sitecore.Data.Items.Item settingsFolder = Sitecore.Context.Database.GetItem(Sitecore.Context.Site.ContentStartPath + "/settings");
In Sitecore 6, the Sitecore LinkManager uses the context to render an URL, as internal links in the Rich Text Editor is stored internally as a GUID, but when rendered, the GUID is replaced with a path relative to the current context of the GUID. So in my case: if a page below website1 links to a page below website2, the LinkManager uses the context of website2 to generate the relative path, even when the calling page is in the context of website1.
The LinkManager uses this little partytrick to allow you to cross-reference different websites and still get the right URL.