0

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?

3

Here 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.

Quick run through:

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.

Complete code:

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.