How to Get the DataSource of a Sublayout

This article describes how to get the datasource of a Sublayout. This is useful when you want to display content from a separate source than the current (context) item.
16 April 2014

Code to get the datasource of a sublayout

protected void Page_Load(object sender, EventArgs e)
{
  var sublayout = this.Parent as Sitecore.Web.UI.WebControls.Sublayout;
  if (sublayout != null)
  {
    Guid dataSourceId;
    Sitecore.Data.Items.Item dataSource;
    if (Guid.TryParse(sublayout.DataSource, out dataSourceId))
    {
      dataSource = Sitecore.Context.Database.GetItem(new ID(dataSourceId));
    }
    else
    {
      dataSource = Sitecore.Context.Database.GetItem(sublayout.DataSource);
    }
    fldTitle.Item = dataSource;
    //TODO set any other FieldRenderers here
  }
}

Note: if you're using Sitecore 7 onwards, the datasource will be returned as a GUID string. For earlier versions of Sitecore the datasource will be a path string. This is the reason for the if statement.

A sample base class

public class SublayoutBase : UserControl
{
  private Item _dataSource;

  public Item DataSource
  {
    get
    {
      if (_dataSource == null)
      {
        if (Parent is Sublayout)
        {
          var sublayout = (Sitecore.Web.UI.WebControls.Sublayout)Parent;
          Guid dataSourceId;
          if (Guid.TryParse(sublayout.DataSource, out dataSourceId))
          {
            _dataSource = Sitecore.Context.Database.GetItem(new ID(dataSourceId));
          }
          else
          {
            _dataSource = Sitecore.Context.Database.GetItem(sublayout.DataSource);
          }
        }
        if (_dataSource == null)
        {
          _dataSource = Sitecore.Context.Item;
        }
      }
      return _dataSource;
    }
  }

  protected override void OnLoad(EventArgs e)
  {
    foreach (Control c in Controls)
    {
      SetFieldRenderers(DataSource, c);
    }
    base.OnLoad(e);
  }

  private void SetFieldRenderers(Item item, Control control)
  {
    if (item != null)
    {
      var ctrl = control as Sitecore.Web.UI.WebControl;
      if (ctrl != null && !string.IsNullOrEmpty(ctrl.DataSource))
      {
        //don't set the source item if the DataSource has already been set. 
        return;
      }
      if (control is FieldRenderer)
      {
        var fr = (FieldRenderer)control;
        fr.Item = item;
      }
      else if (control is Image)
      {
        var img = (Image)control;
        img.Item = item;
      }
      else if (control is Link)
      {
        var link = (Link)control;
        link.Item = item;
      }
      else if (control is Text)
      {
        var text = (Text)control;
        text.Item = item;
      }
      else
      {
        foreach (Control childControl in control.Controls)
        {
          SetFieldRenderers(item, childControl);
        }
      }
    }
  }
}

This sample class can be used as a base class in your solution for any sublayout controls. This will recursively set the item source for any FieldRenderer, Image, Link or Text controls on your sublayout. It also handles the case of no datasource being set by using the context item instead.

Tags: ASP.NETSitecore 101Sublayout
comments powered by Disqus