Wednesday, May 23, 2012

Access Lists in Variation TobWeb

I’m working on a SharePoint project that uses the Variations feature to support multiple languages in regions. Basically I have a Global site (A SP Site Collection) which supports only English so does not have variations setup and I have a set of Regional sites (Again SP Site Collections), where the variations are set up and supports multiple languages.


















Most of the Webparts I implement will be reused in both Global site as well as in Regional sites. One such Webpart is Footer Links control, which will read data from a SP List called FooterLinksList. When in one of the Regional sites, the FooterLinksList reside in the top level site of the variation. This requirement came because of the footer links are region specific as well as language specific. When in the Global site the FooterLinksList reside in the root level of the site collection.
Now the complication is we cannot use SPContext.Current.Site.RootWeb to access list instance since in regional sites, list instances resides one level below the root level. Also we cannot use SPContext.Current.Web to access list instance since 3rd or 4th level sub-sites in the variations does not have the FooterLinksList list instance.
So the solution was to have a common function to find the top site. In case of Global, it is the root web, in case of Regional; it is the Variation Top Site.
/// <summary>
/// Get the top Site - SPWeb having all the list instances.
/// </summary>
/// <returns>The top SPWeb</returns>
[method: CLSCompliant(false)]
public static SPWeb GetTopSite()
{
  string currentUrl = SPContext.Current.Web.Url;
  ReadOnlyCollection<VariationLabel> variationLabels = Variations.Current.UserAccessibleLabels;

  foreach (VariationLabel vl in variationLabels)
  {
    if (currentUrl.StartsWith(vl.TopWebUrl, StringComparison.CurrentCultureIgnoreCase))
    {
      Regex urlValue = new Regex(SPContext.Current.Site.Url, RegexOptions.IgnoreCase);
      string sharepointWebToGo = urlValue.Replace(vl.TopWebUrl, string.Empty).Trim('/');
      return SPContext.Current.Site.OpenWeb(sharepointWebToGo);
    }
  }
  // When in the Global site.
  return SPContext.Current.Site.OpenWeb();
}


Here note that in order to simplify the usage of this method, I used SPContext.Current.Site.OpenWeb() instead of SPContext.Current.Site.RootWeb. So I can dispose the SPWeb object as below.

using (SPWeb web = Utility.GetTopSite())
{
  if (web != null)
  {
    SPList actionpanellList = web.Lists.TryGetList(ActionItemsListName);
    if (actionpanellList != null)
    {
      // ...
    }
  }
}

No comments: