In Sitecore you can apply a datasource to a sublayout when adding it to a template/item. But the datasource is not automatically used. Your context will not change to the item specified in the datasource.
The datasource is therefore not used as a context change – but it can be. All you need is to use the brilliant code provided by Alexey Rusakov and alter it a bit.
Here is my thoughts: I apply a sublayout to a page. I then alter the datasource because I want the sublayout to get it’s data from another item than the current one.
First I have rewritten the code from Alexey into a function that will return the RenderingDefinition from a specific sublayout on the current item for the current context. All you need is the path to the sublayout in question:
using Sitecore.Layouts;
using Sitecore.Data.Items;
private RenderingDefinition GetRenderingDefinition(string path)
{
// Get the Layout definition from the current item
string rend = Sitecore.Context.Item.Fields["__renderings"].Value;
LayoutDefinition layout = LayoutDefinition.Parse(rend);
// Get the current device definition
DeviceDefinition device = layout.GetDevice(Sitecore.Context.Device.ID.ToString());
// Get the sublayout to find
Item mySublayout = Sitecore.Context.Database.Items[path];
// Get the definition for the sublayout
RenderingDefinition rendering = device.GetRendering(mySublayout.ID.ToString());
return rendering;
}
I can then use the RenderingDefinition to get the item that the datasource is pointing to. If there is no datasource it means that no datasource have been applied and I’ll use the current item:
private Item GetCurrentItem()
{
RenderingDefinition def = GetRenderingDefinition("/sitecore/layout/Sublayouts/MySubLayout");
if (def.Datasource == String.Empty)
return Sitecore.Context.Item;
Item dataSourceItem = Sitecore.Context.Database.GetItem(def.Datasource);
Sitecore.Diagnostics.Assert.IsNotNull(dataSourceItem, "Could not find datasource item at " + def.Datasource);
return dataSourceItem;
}
In my codebehind for the sublayout I use the item returned by the GetCurrentItem() function instead of the Sitecore.Context.Item, and voila! I have my context change.
BTW: The RenderingDefinition contains much more than the datasource. You can also get the parameters, placeholder and caching informations.
Subnote: Alexey Rusakov describes on his blog that in Sitecore 6 you can use the Attributes["sc_parameters"] to get the parameters for a sublayout. That’s true, but the parameters does not contain the datasource, only the parameters.
November 25, 2009 at 4:53 pm
Great article! This has been very helpful for me, so thank you. The issue I’m encountering with this code however is when I attempt to place multiple instances of the same SubLayout on a page, each with their own unique Datasource definitions. I can’t get each instance of the SubLayout to recognize its own unique Datasource. It seems like it should be simple to fix this, but I’m stuck!