I want to provide the Profile
and Pattern Card
names for a particular rendering to global javascript variables on the front end.
How can I programmatically lookup these values from the personalisation rules applied to the rendering?
Sitecore Stack Exchange is a question and answer site for developers and end users of the Sitecore CMS and multichannel marketing software. It only takes a minute to sign up.
Sign up to join this communityHere is the C# portion of the code solution I came up with. Once you have the variables writing them into the rendered HTML is straight forward.
To use this just call one the methods GetMatchedProfileName
or GetMatchedPatternCardName
(code below). You can then write the resulting string into into your MVC model and render them in the view.
A) Get a reference to all the renderings on the page:
var allReferences = GetRenderingsForControl(contextItem, device).ToList();
B) Find the matching rendering reference:
var renderingReferrence = allReferences.Where(i => ID.Parse(i.UniqueId).Equals(renderingId)).FirstOrDefault();
C) Lookup the rule context and run the first matching rule:
var ruleContext = new ConditionalRenderingsRuleContext(allReferences, renderingReferrence);
renderingReferrence.Settings.Rules.RunFirstMatching(ruleContext);
D) Lookup the datasource
that has been selected after running the rule.
string personalizedDatasource = ruleContext.Reference.Settings.DataSource;
e) The remaining code uses the method GetMatchedProfile
to loop over the Actions and Conditions to obtain the matching condition. The matching condition contains the profile and pattern card name.
public string GetMatchedProfileName(ID renderingId, Item contextItem, DeviceItem device)
{
var ruleMatch = GetMatchedProfile(renderingId, contextItem, device);
return ruleMatch.ProfileName;
}
public string GetMatchedPatternCardName(ID renderingId, Item contextItem, DeviceItem device)
{
var ruleMatch = GetMatchedProfile(renderingId, contextItem, device);
return ruleMatch.PatternName;
}
private HasPatternCondition<ConditionalRenderingsRuleContext> GetMatchedProfile(ID renderingId, Item contextItem, DeviceItem device)
{
var allReferences = GetRenderingsForControl(contextItem, device).ToList();
var renderingReferrence = allReferences.Where(i => ID.Parse(i.UniqueId).Equals(renderingId)).FirstOrDefault();
var ruleContext = new ConditionalRenderingsRuleContext(allReferences, renderingReferrence);
if (!ruleContext.Reference.Settings.Rules.Rules.Any())
return null;
renderingReferrence.Settings.Rules.RunFirstMatching(ruleContext);
string personalizedDatasource = ruleContext.Reference.Settings.DataSource;
var ruleMatch = GetMatchedProfile(ruleContext, personalizedDatasource);
return ruleMatch;
}
private RenderingReference[] GetRenderingsForControl(Item contextItem, DeviceItem device)
{
if (contextItem != null)
{
var renderings = contextItem.Visualization.GetRenderings(device, true);
return renderings;
}
return new RenderingReference[0];
}
private HasPatternCondition<ConditionalRenderingsRuleContext> GetMatchedProfile(ConditionalRenderingsRuleContext ruleContext, string personalizedDatasource)
{
foreach (var rule in ruleContext.Reference.Settings.Rules.Rules)
{
foreach (var action in rule.Actions)
{
var setDataSourceAction = action as SetDataSourceAction<ConditionalRenderingsRuleContext>;
if (setDataSourceAction != null && setDataSourceAction.DataSource == personalizedDatasource)
{
var conditionMatch = rule.Condition as Sitecore.Analytics.Rules.Conditions.HasPatternCondition<ConditionalRenderingsRuleContext>;
if (conditionMatch != null)
{
return conditionMatch;
}
}
}
}
return null;
}
This answer uses some of the code from Run personalization rule programatically to lookup rendering references.