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.