Sitecore Rule – Personalize based on any field in any facet in your Contact

This Sitecore Personalization Rule was developed by my colleague Martin Rygaard with the purpose of being able to personalize on any field in any facet on a contact.

Contact Facet Rule Set Editor

Contact Facet Rule Set Editor

STEP 1: CREATE THE CONDITION

Create a new “Condition” below /sitecore/system/Settings/Rules/Definitions/Elements/???

The text of the Condition is:

where the [facetpath,,,facetpath] has [facetvalue,,,facetvalue]

STEP 2: CREATE A WHENCONDITION

This condition traverses the Contact path and returns true if the value matches the value described:

using System.Collections;
using Sitecore.Analytics;
using Sitecore.Analytics.Model.Framework;
using Sitecore.Analytics.Tracking;
using Sitecore.Diagnostics;
using Sitecore.Rules;
using Sitecore.Rules.Conditions;

namespace MyNamespace
{
  public class ContactFacetHasValue<T> : WhenCondition<T> where T : RuleContext
  {
    public string FacetValue { get; set; }
    
    public string FacetPath { get; set; }

    protected override bool Execute(T ruleContext)
    {
        Contact contact = Tracker.Current.Session.Contact;

        if (contact == null)
        {
          Log.Info(this.GetType() + ": contact is null", this);
          return false;
        }

        if (string.IsNullOrEmpty(FacetPath))
        {
          Log.Info(this.GetType() + ": facet path is empty", this);
          return false;
        }

        var inputPropertyToFind = FacetPath;

        string[] propertyPathArr = inputPropertyToFind.Split('.');
        if (propertyPathArr.Length == 0)
        {
          Log.Info(this.GetType() + ": facet path is empty", this);
          return false;
        }

        Queue propertyQueue = new Queue(propertyPathArr);
        string facetName = propertyQueue.Dequeue().ToString();
        IFacet facet = contact.Facets[facetName];
        if (facet == null)
        {
          Log.Info(string.Format("{0} : cannot find facet {1}", this.GetType(), facetName), this);
          return false;
        }

        var datalist = facet.Members[propertyQueue.Dequeue().ToString()];
        if (datalist == null)
        {
          Log.Info(string.Format("{0} : cannot find facet {1}", this.GetType(), facetName), this);
          return false;
        }
        
        if(typeof(IModelAttributeMember).IsInstanceOfType(datalist))
        {
          var propValue = ((IModelAttributeMember)datalist).Value;
          return (propValue != null ? propValue.Equals(FacetValue) : false);
        }
        if(typeof(IModelDictionaryMember).IsInstanceOfType(datalist))
        {
          var dictionaryMember = (IModelDictionaryMember) datalist;

          string elementName = propertyQueue.Dequeue().ToString();
          IElement element = dictionaryMember.Elements[elementName];
          if (element == null)
          {
            Log.Info(string.Format("{0} : cannot find element {1}", this.GetType(), elementName), this);
            return false;
          }

          string propertyToFind = propertyQueue.Dequeue().ToString();
          var prop = element.Members[propertyToFind];
          if (prop == null)
          {
            Log.Info(string.Format("{0} : cannot find property {1}", this.GetType(), propertyToFind), this);
            return false;
          }

          var propValue = ((IModelAttributeMember) prop).Value;
          return (propValue != null ? propValue.Equals(FacetValue) : false);
        }
        if (typeof(IModelCollectionMember).IsInstanceOfType(datalist))
        {
          var collectionMember = (IModelCollectionMember)datalist;
          var propertyToFind = propertyQueue.Dequeue().ToString();
          for (int i = 0; i < collectionMember.Elements.Count; i++)
          {
            IElement element = collectionMember.Elements[i];
            var prop = element.Members[propertyToFind];
            if (prop == null)
            {
              Log.Info(string.Format("{0} : cannot find property {1}", this.GetType(), propertyToFind), this);
              return false;
            }
            var propValue = ((IModelAttributeMember) prop).Value;
            if (propValue.Equals(FacetValue))
              return true;
          }
        }

      return false;
    }
  }
}

STEP 3: TEST IT

This is an example of a Contact, with facets, among these is the “Personal” facet with the “FirstName” attribute:

Facet

Facet

When creating a Personalization rule where “Personal.FirstName” has “Brian” and applying it to my page:

Contact Facet Rule Set Editor

Contact Facet Rule Set Editor

Rule In Use

Rule In Use

I should only be able to see this title when logged in as a user which contact facet FirstName is “Brian”:

Yes, I am a Brian

Yes, I am a Brian

MORE TO READ:

 

 

Advertisements

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in .net, c#, Sitecore 7, Sitecore 8 and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s