Sitecore’s API contains an easy way to get the context site in your code, however it has some pitfalls in the case of a multi-site solution with page editor and preview modes. Here is a simple solution to this challenge.
Standard API Context Site Resolution
The typical way to get a context site in Sitecore is simply via Sitecore.Context.Site
. This works most of the time, but if you have a multi-site solution and use Page Editor or Preview mode, it may not determine the site the item lives within (due to co-habitating site content trees). Additionally, if you use the Presentation tab’s embedded Preview frame, it will assume the context site is either “website” or “shell” so you really need this solution.
Enhanced Context Site Resolution
Here is a sample method to get the context site. I won’t go into details of the code because it’s all commented, but at a high-level:
- Get the item being viewed (the hardest part) — page editor or multiple preview modes
- Get all sites
- Find the first site for which the item falls within the tree path
[csharp]
public static Sitecore.Sites.SiteContext GetContextSite()
{
if (Sitecore.Context.PageMode.IsPageEditor || Sitecore.Context.PageMode.IsPreview)
{
// item ID for page editor and front-end preview mode
string id = Sitecore.Web.WebUtil.GetQueryString("sc_itemid");
// by default, get the item assuming Presentation Preview tool (embedded preview in shell)
var item = Sitecore.Context.Item;
// if a query string ID was found, get the item for page editor and front-end preview mode
if (!string.IsNullOrEmpty(id))
{
item = Sitecore.Context.Database.GetItem(id);
}
// loop through all configured sites
foreach (var site in Sitecore.Configuration.Factory.GetSiteInfoList())
{
// get this site’s home page item
var homePage = Sitecore.Context.Database.GetItem(site.RootPath + site.StartItem);
// if the item lives within this site, this is our context site
if (homePage != null && homePage.Axes.IsAncestorOf(item))
{
return Sitecore.Configuration.Factory.GetSite(site.Name);
}
}
// fallback and assume context site
return Sitecore.Context.Site;
}
else
{
// standard context site resolution via hostname, virtual/physical path, and port number
return Sitecore.Context.Site;
}
}
[/csharp]
Thanks for this great tip. I’ve been searching the web for quite a while and it was very usefull.
That’s a very nice solution, thanks.
Understand this is an old post. But for the record of saying, Sitecore has provided a patch for this
https://kb.sitecore.net/articles/382913. Hope someone coming referring to this post gets benefitted.