Skip to content

Instantly share code, notes, and snippets.

@blacktambourine
Last active August 22, 2017 08:34
Show Gist options
  • Save blacktambourine/9573265cec679134128c7e628f7aff0b to your computer and use it in GitHub Desktop.
Save blacktambourine/9573265cec679134128c7e628f7aff0b to your computer and use it in GitHub Desktop.
Get Personalised Datasource from a View Rendering
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Layouts;
using Sitecore.Rules;
using Sitecore.Rules.ConditionalRenderings;
namespace BlackTambourine.Core.Sitecore.Helpers
{
/// <summary>
/// Functions to get the Datasources for a particular instance of a Rendering
/// based on these:
/// https://blog.horizontalintegration.com/2015/09/08/programmatically-get-datasource-items-of-a-sitecore-item/
/// https://blog.horizontalintegration.com/2015/09/08/programmatically-get-personalization-datasource-items-of-a-sitecore-item/
/// </summary>
public class RenderingDatasourceHelper
{
/// <summary>
/// Get the Personalised Datasource(s) from a particular Placeholder and View Rendering on an item
/// </summary>
/// <param name="device"></param>
/// <param name="i">Item which has the placeholder on it</param>
/// <param name="placeholderName">Presentation Settings Placeholder Name</param>
/// <param name="renderingId">ID of the View Rendering used in this Placeholder</param>
/// <returns>List of Sitecore Items used as datasources in these View Renderings</returns>
public static List<Item> GetPersonalisedPlaceHolderDatasourceItems(DeviceItem device, Item i, string placeholderName, ID renderingId)
{
var result = new List<Item>();
var renderingReferences = GetRenderingReferences(device, i, placeholderName, renderingId).ToList();
result = renderingReferences
.SelectMany(x=> GetPersonalizationDataSourceItem(x, i))
.Where(y => y != null)
.ToList();
return result;
}
#region Methods to get the Datasources
private static IEnumerable<Item> GetPersonalizationDataSourceItem(RenderingReference reference, Item i)
{
var list = new List<Item>();
//if no datasource
if (reference == null)
{
return list;
}
//else if no Personalisation is used, return the default datasource
if (reference.Settings.Rules == null || reference.Settings.Rules.Count <= 0)
{
var item = GetDataSourceItem(reference);
if (item != null)
{
list.Add(item);
}
return list;
}
//note: doesn't support personalisation of the component with multiple renderings
var ruleContext = new ConditionalRenderingsRuleContext(new List<RenderingReference> {reference}, reference)
{
Item = i
};
reference.Settings.Rules.RunFirstMatching(ruleContext);
list.Add(GetDataSourceItem(reference.Settings.DataSource, reference.Database));
//else Get the Personalised datasource
//foreach (var r in reference.Settings.Rules.Rules)
//{
// if (r.Evaluate(ruleContext))
// {
// list.AddRange(r.Actions
// .OfType<SetDataSourceAction<ConditionalRenderingsRuleContext>>()
// .Select(setDataSourceAction => GetDataSourceItem(setDataSourceAction.DataSource, reference.Database))
// .Where(dataSourceItem => dataSourceItem != null));
// return list; //break from loop on first evaluated
// }
//}
return list;
}
private static IEnumerable<RenderingReference> GetRenderingReferences(DeviceItem device, Item i, string placeholderName, ID renderingId)
{
return i == null
? new RenderingReference[0]
: i.Visualization.GetRenderings(device, false).Where(x => x.Placeholder == placeholderName && x.RenderingID == renderingId);
}
private static Item GetDataSourceItem(RenderingReference reference)
{
return reference != null
? GetDataSourceItem(reference.Settings.DataSource, reference.Database)
: null;
}
private static Item GetDataSourceItem(string id, Database db)
{
Guid itemId;
return Guid.TryParse(id, out itemId)
? db.GetItem(new ID(itemId))
: db.GetItem(id);
}
#endregion
}
}
@blacktambourine
Copy link
Author

Some bug fixes applied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment