Sitecore Custom Personalization Rule

November 28, 2016

Blog | Development | Sitecore Custom Personalization Rule

In this post, I walked thru the need to store Facet data on a Contact in order to hide/show a component on the front end. The original concrete example of that post was: on a project I have been working on, on their homepage, there is a Help Message component that will show on the page until either the message expires or the user clicks the Don't show me this anymore button on the message. Since the last post covered where to store that data, we will now cover how to leverage facets in order to drive the front-end renderings thru the use of a custom Personalization Rule. Let’s start by creating the actual code that will be triggered by the condition. We need to create a class that inherits from the Sitecore.Rules.RuleContext and implement the Execute() method. The Execute() method is where all the logic will reside:

namespace Yourproject.Namespace.Conditions
{
  public class HideMessageRule<T> : StringOperatorCondition<T> where T : RuleContext
  {
    public int Value { get; set; }
    protected override bool Execute(T ruleContext) {
      Assert.IsNotNull(Tracker.Current, "Tracker.Current is not initialized");
      Assert.IsNotNull(Tracker.Current.Contact, "Tracker.Current.Contact is not initialized");
      bool matchFound = false;
      try {
        var conditionalRenderingsRuleContext = ruleContext as ConditionalRenderingsRuleContext;
        var datasourceId = conditionalRenderingsRuleContext.Reference.Settings.DataSource;
        var hiddenMessages = Tracker.Current.Contact.GetFacet("Hidden Messages");
        var messages = hiddenMessages.Messages;
        matchFound = messages.Any(g => g.ItemHidden.Equals(Guid.Parse(datasourceId)) && g.TimeHidden.AddDays(Value) >= DateTime.Now);
      }
      catch (Exception ex) {
        Log.Debug(string.Format("HideMessageRule -- {0}", ex.Message));
      }

      return matchFound;
    }
  }
}

In the above snippet, you see that we cast ruleContext as ConditionalRenderingsRuleContext so we can get a true reference (thru conditionalRenderingsRuleContext.Reference) to the item that has the Personalization Rule applied to it. Once we have the actual datasource that is being rendered by the item with personalization, then we grab the Facets from our current Contact and compare. The next step would be to create the actual Rule in the Sitecore tree. Let’s create a new Element Folder under /sitecore/system/Settings/Rules/Definitions/Elements called User Defined (or whatever you prefer, but for our example we will use this). Then under /sitecore/system/Settings/Rules/Definitions/Elements/User Defined let’s create a new Condition called Match Hidden Message with Timeframe. For the newly created condition, set Text to when the current message matches on that has been hidden for the current Contact and was hidden for up to [Value,,,specific value] days. This is the text you will see (and set values for) in the actual personalization prompt. The last and key piece to this new rule definition is to set the Script/Type to the class you created above (YourProject.Namespace.Conditions.HideMessageRule, YourProject).   At this point, the definition should resemble:custompersonalizationrule

You may have noted that the example above has a Value provided from the Sitecore Personalization Rule definition.  The Text field on the definition makes the association to the actual class and casts the value to the needed datatype, allowing you to take input and run your own comparisons. There are a lot permutations around the conditionals and values that can be used in the Text (for example where the message name [OperatorId, StringOperator,,compares to] [Value,,,specific value]) that make this quite powerful. So at the moment, we should have the code needed, the definition created, now we just need to add the rule to a rendering in the presentation details. To assign rules to a rendering, on the desired page, go to Presentation Details click Edit on the desired device, click on the desired personalized rendering and click Personalize.  From here, add a New Condition, check the Hide Component checkbox, and click Edit.  This will bring up all available rules, search for the one you created, add and update the necessary values.  The rule itself should look similar to this:presdetails2

Once that is set, and all necessary items published, the code that executes the rule should be active and, given one of the Messages were hidden by the user, the Help Message should now no longer render. With this and custom faceting I was able to achieve my goal of storing and querying faceted data on the contact and using that to drive the page view itself, and hopefully this will help you in the future too!

Steve VandenBush

Technical Lead
Tags
  • Content Management
  • Personalization
  • Sitecore
  • Web Development
subscribe to GeekHive's newsletter

Never miss out on a Sitecore update again!

Our newsletter features a blog roundup of our top posts so you can stay up to date with industry trends, tutorials, and best practices.

Recent Work

Check out what else we've been working on